-1

echo -e '#!/bin/bash\nsleep 10' > time_test.sh && chmod +x time_test.sh && time time_test.sh

time_test.sh: No such file or directory

real 0m0.186s user 0m0.105s sys 0m0.074s

I must be missing something..?

EDIT: I missed the error, partially because I was ignoring an error in a non-example script (it is added now). The moral seems to be that commands that run the script in some fashion need its location, where as other built-ins like cat dont. So, maybe the better question is, is that a decent definition of which commands need the location, or I suppose just trial and error, if there is an error the script can't be found, to add the ./ or path information.. I suppose anything that fails without it being marked executable. I wonder which other common commands people use that encounter this.

alchemy
  • 597
  • 2
    Your execution would have failed unless you have . in your PATH which you should not do. You have to execute the script like ./time_test.sh or bash time_test.sh – jesse_b Apr 13 '22 at 21:53
  • @jesse_b I'm trying to use time on the script. I need to have something similar to time time_test.sh. I tried time bash time_test.sh already. bash time time_test.sh says "/usr/bin/time: cannot execute binary file". – alchemy Apr 13 '22 at 21:57
  • @alchemy time ./time_test.sh – jesse_b Apr 13 '22 at 21:57
  • @jesse_b same result.. (sorry for the double comment) – alchemy Apr 13 '22 at 21:59
  • Yeah the only time you should get "cannot execute binary file" is from bash time ... but time bash ... or time ./time_test.sh should absolutely not produce that – jesse_b Apr 13 '22 at 22:05
  • @jesse_b understood, but still no joy.. does it work for you? Im on up-to-date Ubuntu 20.04. – alchemy Apr 13 '22 at 22:09
  • @KamilMaciorowski sorry, I am blind.. yes there is.. I corrected the output – alchemy Apr 13 '22 at 22:21
  • @jesse_b my bad.. you are correct. I switched VMs to make sure my shell options I had messed with werent affecting it.. and it didnt find the file. But adding ./ works. So all commands that run a script have to be told where it is, versus builtins like cat that can see it in the pwd..? – alchemy Apr 13 '22 at 22:28
  • @KamilMaciorowski, so I had some other errors in a non-example script that I was troubleshooting, that I was ignoring visually.. dont know why didnt see that.. you were correct. – alchemy Apr 13 '22 at 22:31
  • What happens when you run the script without time? How are you running it? – ctrl-alt-delor Apr 13 '22 at 22:33
  • @ctrl-alt-delor jesse_b and Kamil got it.. time needs the explicit location of the script to run. – alchemy Apr 13 '22 at 22:37
  • is this not also true of your shell? – ctrl-alt-delor Apr 13 '22 at 22:38
  • @ctrl-alt-delor other non-executing commands of course dont need the explicit location if running in the pwd of the script. Sorry, silly mistake I could have seen the error for, but maybe this will help someone else out. – alchemy Apr 13 '22 at 22:45
  • If you PATH includes ., then you should fix it. It is a serous security vulnerability (e.g. make an executable script called ls, then try to check for its existence using ls. Hopefully the script does nothing bad), and can also lead to much annoyance. – ctrl-alt-delor Apr 13 '22 at 23:04
  • @ctrl-alt-delor great, thanks.. that is actually not the problem – alchemy Apr 13 '22 at 23:10
  • The convention is time_test.sh means a file in the current working directory if we're about to read or write to the file. If we're about to execute time_test.sh then by convention it means a file named time_test.sh somewhere in $PATH. Note . is usually not in $PATH, so to execute ./time_test.sh you need to explicitly write this ./. There are subtleties, e.g. bash time_test.sh works because it reads the file (to interpret it, but the file does not need to be executable). time time_test.sh is simple though: it tries to truly execute time_test.sh, so it uses $PATH. – Kamil Maciorowski Apr 13 '22 at 23:26

1 Answers1

2

This was already answered in the comments, but I will answer it here as you seem to have missed it.

When you run a command, it searches for the command file in the directories listed in your $PATH variable (unless the command is an alias or a shell function). This usually does not include the current working directory (this differs from MS-Windows), because this would cause security problems, e.g. making a script called ls.

Solution: run the script using time ./time_test.sh not with time time_test.sh. (note: the file should not end with a .sh, it is bad form, and leaks implementation details.)

Kusalananda
  • 333,661
  • Just to be technical here, "When you run a command.." should be "When you run a command that executes a file" I think. That was my issue. I added a bit more context in the Question. – alchemy Apr 13 '22 at 22:44
  • No. It does it script or not. It is part of the Unix philosophy, that everything that is executable is a command/program. The language does not matter. Are you running scripts with bash script-name. If so then don't. You made it executable, you added a #! line. – ctrl-alt-delor Apr 13 '22 at 22:49
  • I think youre missing how simple my issue was.. compare to cat <file> that does not need the ./ for example cat ./<file>.. but a command like time executing does. – alchemy Apr 13 '22 at 22:51
  • @alchemy Looking at the content of a file, e.g., using cat is generally less destructive than executing the contents of the file. So cat <file> will look for in the relative path. To execute <file>, the program needs to be in your $PATH or you need to give an explicit path name in the command. – doneal24 Apr 13 '22 at 22:59
  • @doneal24 yes, thanks.. I just dont use commands that often that execute files/scripts manually (beside bash or . occasionally) – alchemy Apr 13 '22 at 23:01
  • @doneal24 Actually file writing can be destructive echo > which doesnt need explicit location (although I use set -o noclobber).. I suppose it might be more clear if it did.. but again I wonder how many other commands like time even show this distinction. – alchemy Apr 13 '22 at 23:09
  • 1
    Yes simple is the point. It is simpler that you think. It looks like you are special casing something. The problem has nothing to do with the time command (no distinction). You will get the same error if just running the command without time. If you can identify what you are doing different (when you don't need to), then it will fix this an a whole lot of future problems. However you have nothing to compare what you are doing, with. Except it self. So all looks good. I can not tell what this variation is, because you only express variance from what you think is normal. – ctrl-alt-delor Apr 13 '22 at 23:10
  • @ctrl-alt-delor I'm using time as an example (the first time I've run into this). It is different than other 'commands' because it executes a file. And this is the identification of the special case. The general case, as I hypothesize while asking for other examples in my edit above, is any command that executes a file. Which is why I suggested you specify that in the answer you provided. Actually, the general case may be more general as @doneal hinted at, but as I replied,much of those exceptions are by design for expediency so I think they unnecessarily complicate the broadest general case – alchemy Apr 13 '22 at 23:30
  • @alchemy time doesn’t execute a file, it executes a command. Try running time ls and cat ls from your home directory to see why it makes sense for the behaviour to be different. – Stephen Kitt Apr 14 '22 at 06:09
  • @StephenKitt does not time do exactly what the shell does. When you type ls both fork then both call one of the exec?p?s. I suspect the difference may be the OP calling bash file-name. Here bash is being different. – ctrl-alt-delor Apr 14 '22 at 10:39
  • @ctrl-alt-delor yes, bash file-name executes a file, not a file, not a command. The point I’m trying to make is that alchemy’s generalisation doesn’t work, because most of the time what gets executed isn’t a named file (something that gets resolved using only the file system, by default in the current directory), but a named command (something that gets resolved with PATH etc.). – Stephen Kitt Apr 14 '22 at 10:53
  • @StephenKitt I can't tell if we are in agreement (but suspect we are). – ctrl-alt-delor Apr 14 '22 at 13:10
  • @ctrl-alt-delor I think we are. My comment got messed up, I meant to write “bash file-name executes a file, not a command”. – Stephen Kitt Apr 14 '22 at 13:13
  • @StephenKitt fair enough, the need for ./ is when running a command that executes something. time can execute either a file (a script, as in my case) or a command. – alchemy Apr 14 '22 at 16:58
  • 1
    @Kusalananda I avoided details on PATH on purpose. The OP way not be ready, for this level of detail. – ctrl-alt-delor May 08 '22 at 12:56
  • @ctrl-alt-delor I see. You do what you think is right. – Kusalananda May 08 '22 at 12:57