-1

I have a script named Run_at_startup.sh, which contains the following line:

/bin/bash "$(pwd)/Testing_3.sh"

If I manually run Run_at_startup.sh, Testing_3.sh will be run properly. However, if Run_at_startup.sh is run via crontab, Testing_3.sh will not be run. Obviously, the problem lies in $(pwd). So, is it impossible to use $(pwd) in a script run via crontab? If so, what can be used instead of $(pwd)?

roaima
  • 107,089
  • 14
  • 139
  • 261
Matthew Wai
  • 427
  • 3
  • 10
  • 16
  • 3
    If your script assumes that you are in a particular directory before you run the script, make sure that your cron job first uses `cd` to change to that directory. I'm just guessing that this is the issue, so I'm not turning this into a real answer. – Kusalananda Nov 18 '22 at 12:56
  • 2
    See also [What is the 'working directory' when cron executes a job?](https://unix.stackexchange.com/q/38951) which your question may be a duplicate of. – Kusalananda Nov 18 '22 at 12:58
  • 2
    Why are you using `$(pwd)`, why would you need this to be dynamic instead of using the actual path? – terdon Nov 18 '22 at 14:31
  • @Kusalananda, after referring to your link, I found a simple solution. Please read my answer below. – Matthew Wai Nov 18 '22 at 16:05
  • @terdon, Next time, if the full absolute path is different, I will have to modify the script. If I forget to modify it, it will fail. – Matthew Wai Nov 19 '22 at 03:17

3 Answers3

3

If you want to run a script that lies in the current working directory of the process invoking it, just use ./that-script.

"$(pwd)/that-script" in POSIX-like shells (and cron should invoke a POSIX-like shell to parse the commands lines) is a poorer version of "$PWD/that-script". Poorer because it has to run an extra process and also because $(...) strips all trailing newline characters, so it won't work if the path to the current working directory stored in $PWD ends in newline characters.

The difference between ./that-script and "$PWD/that-script" (which will be expanded to /path/to/working/directory/that-script) is that the former is a relative path and the latter in an absolute path. In either case, if that-script is not to be found in the current working directory of the shell process that cron invokes to parse that command line, that will fail.

By default jobs in your crontab are generally started in your home directory.

If that-script is not in that directory, you'd use /actual/path/to/that-script. If it were also important that the script be run with its current working also directory being /actual/path/to, you'd do:

cd /actual/path/to && ./that-script

Or:

cd /actual/path/to && "$PWD/that-script"

If you want to run that-script from another-script and both scripts reside in the same directory. You can generally derive that directory from the value of $0 in other-script.

For instance, if other-script is a zsh script:

bash -- $0:h/that-script

If not and assuming $0 doesn't end in newline characters:

bash -- "$(dirname -- "$0")/that-script"

The dirname of $0 may be a relative path. To make it an absolute path, you can do, in zsh:

bash -- $0:P:h/that-script

Other shells:

dir=$(CDPATH= cd -P -- "$(dirname -- "$0")" && pwd -P) || exit
bash -- "$dir/that-script"
Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
0

pwd returns a current directory. Each time you do cd somedir, the result of pwd changes.

So, if /bin/bash "$(pwd)/Testing_3.sh" works fine at startup. Do

echo "$(pwd)/Testing_3.sh"

The result would the string you need to use in crontab.

White Owl
  • 4,511
  • 1
  • 4
  • 15
0

After referring to the link posted by Kusalananda, I found the following solution:

/bin/bash "$(dirname "$0")/Testing_3.sh"

$(dirname "$0") works fine in a bash script run via crontab.

Matthew Wai
  • 427
  • 3
  • 10
  • 16