I am running bash scripts from java programs on a server. I just uploaded a new version of the script intending the next run of the script to use the version. I did not mean
I'm not sure if things have changed since mob's answer, which has been accepted, but in bash 4.3.46 (such as comes with ubuntu 16.04), it is true that bash monitors the script file for changes, but this is broken if the file is deleted.
So a slight modification to his script does the 'right' thing:
# If you modify a script, will it change the behavior of
# processes that are currently running that script?
# Does this script print "Foo" or "Bar"?
cat >foo.sh <<EOF
sleep 5
echo Foo
EOF
bash foo.sh &
sleep 2
rm foo.sh
cat >foo.sh <<EOF
sleep 5
echo Bar
EOF
wait
This now prints Foo
.
Deleting the script is one thing, but modifying it may produce more "interesting" results.
Also, changing a file that is replicated and/or network-mounted introduces behavior specific to the filesystem and deployment protocols. These are not going to be modelled accurately by a simple test on a local hard mount or one where a network mount is modified on the same system that is reading the file.
Furthermore, "uploading" this file to 300 servers introduces all kinds of wonderful complexity that us overflowians probably don't have nearly enough information to analyze.
ISTM that your issues probably are related to the update. I think the mystery commands may come from bash reading part of a script from the old version and part from the new version. I do know that you should probably shut down the subsystem, if possible, while updating.
Upon invocation, bash will fork off a new process and load the script into memory. Unless the script references itself, it should still work. Here is an example of a script both deleting itself from disk and still working until it tries to access itself via $0
#!/bin/bash
echo "I can't take it anymore"
echo "Goodbye World!"
rm -f "$0"
echo "Wait, I change my mind!"
sed 's/Goodbye/Hello/' "$0"
$ ./suicide.sh
I can't take it anymore
Goodbye World!
Wait, I change my mind!
sed: can't read ./suicide.sh: No such file or directory
SiegeX is half right - bash will load an entire script into memory, so a script can continue to run even if it's source file is deleted while the process is running. But bash will also check whether the source file is updated while the script is running. If it has been, bash will reload it and continue running it from the current position reopen the file, seek to the current position of the script, and continue running the script from that point.
Here's a proof-of-concept script:
# If you modify a script, will it change the behavior of
# processes that are currently running that script?
# Does this script print "Foo" or "Bar"?
cat >foo.sh <<EOF
sleep 5
echo Foo
EOF
bash foo.sh &
sleep 2
cat >foo.sh <<EOF
sleep 5
echo Bar
EOF
wait
So the upshot is don't modify the source files of bash scripts if you care about the processes that are currently running that script.
(This script, however, displays "Foo". The "current position" of the bash script is always at the beginning or end of a line.)
echo "sleep 5 ; echo Foo" > foo.sh
bash foo.sh &
sleep 2
echo "sleep 5 ; echo Bar" > foo.sh
wait