2 ms·
> So I guess bash or whatever does an mmap of the script it’s running this is incorrect, and is relatively easy to test: $ strace -y -P /tmp/test.sh bash /t
by Hello71 5y ago
> So I guess bash or whatever does an mmap of the script it’s running
this is incorrect, and is relatively easy to test:
$ strace -y -P /tmp/test.sh bash /tmp/test.sh
ioctl(3</tmp/test.sh>, TCGETS, 0x7ffc6daea580) = -1 ENOTTY (Inappropriate ioctl for device)
lseek(3</tmp/test.sh>, 0, SEEK_CUR) = 0
read(3</tmp/test.sh>, "#!/bin/sh\n", 80) = 10
lseek(3</tmp/test.sh>, 0, SEEK_SET) = 0
dup2(3</tmp/test.sh>, 255) = 255</tmp/test.sh>
close(3</tmp/test.sh>) = 0
fcntl(255</tmp/test.sh>, F_SETFD, FD_CLOEXEC) = 0
fcntl(255</tmp/test.sh>, F_GETFL) = 0x8000 (flags O_RDONLY|O_LARGEFILE)
newfstatat(255</tmp/test.sh>, "", {st_mode=S_IFREG|0644, st_size=10, ...}, AT_EMPTY_PATH) = 0
lseek(255</tmp/test.sh>, 0, SEEK_CUR) = 0
read(255</tmp/test.sh>, "#!/bin/sh\n", 10) = 10
read(255</tmp/test.sh>, "", 10) = 0
the reason why modifying a script during execution can have unpredictable results, not demonstrated in this test, is that Unix shells traditionally alternate between reading commands and executing them, instead of reading the entire file (potentially very large compared to 1970s RAM size) and executing commands from the in-memory copy. on modern systems, shell script sizes are usually negligible compared to system RAM. therefore, you can manually cause the entire file to be buffered by enclosing the script in a function or subshell:
#!/bin/sh
main() {
# script goes here
}
main