-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
  • 537
  • 5
  • 16
  • 2
    Your execution would have failed unless you have `.` in your PATH which you [should not do](https://unix.stackexchange.com/q/65700/237982). 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
  • 320,670
  • 36
  • 633
  • 936
ctrl-alt-delor
  • 27,473
  • 9
  • 58
  • 102
  • 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 ` that does not need the `./` for example `cat ./`.. 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 ` will look for in the relative path. To execute ``, 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