I have a bash script:
#! usr/bin/env bash
# test bash script to call python scripts
cd ~/python
for ((i = 1; i <= 2; i++)); do
python3 test_0$i.py; done
cd ~/bash
that pulls test_0x.py files from the python directory and runs them in order.
test_01.py is a single print statement, whereas test_02 is a for loop.
I was expecting it to:
- navigate to ~/python
- run test_01.py
- run test_02.py
- navigate back to ~/bash
the bash script runs test_01.py, then test_01.py again, and only then test_02.py.
is this some quirk of shell-scripts i am simply too green to anticipate, or is there something wrong with my — albeit very basic — code?
I am using an ubuntu terminal through windows subsystem for linux, if that affects things.
2
Answers
I fixed the shebang line, removed the final
cd
command, and then restarted the wsl instance. The bash script now works as i expected it to. I don't know what fixed it, but I suspect that, in my ignorance, I was doing something stupid in the background that caused this error. Thank you to all who answered.Running through WSL should have no impact in this case.
There are a few problems with your script, but the ones that are visible, at least, wouldn’t cause an additional loop.
To debug the loop part of the problem, I’d start by:
From the command-line, run the same loop in the same directory, but with an
echo
in place of the Python invocation itself:If that works, make the same adjustment to the script and test it.
If that works, as mentioned in the comments, check
test_01.py
to see if it is callingtest_02.py
. Try running it manually at the command-line and/or visually inspect it.As @user1934428 mentioned in the comments, running with
set -x
may also yield useful information.Other issues
There is a typo in your shebang line (at least as you entered it here in your question) –
#! usr/bin/env bash
. The purpose of a shebang line is to tell system what program should execute your script (e.g., when called as./script.sh
). This is simply not going to work.The proper shebang line would be:
However, if you really are expecting it to run as a script, then we come to the second issue. You mention that step 4 should be to "navigate back to ~/bash".
This will not have the intended effect when executing a script via the shebang line. It may appear to work, but what really happens is that the shell will still be in whatever directory it started in. This may be the
~/bash
directory, but it may not be. For example:This would leave you back in the
~
directory after the script completes.Why? When using a shebang line, the script is executed by a separate shell invocation. It’s inside this shell (running as a subprocess) that the
cd
takes place. As acd
is an environment change (thePWD
environment variable), it can’t be propagated back to the calling process.If you really need the script to be able to change the directory for the calling shell (and you probably don’t), then you would need to
source
the script instead of executing it.source script.sh
will process the script inside the currently running Bash shell, allowing it to change the current directory of the current shell.