在 Ubuntu 中,
运行可执行文件或者脚本文件时,如果移动或者重命名该文件,会不会影响运行?
运行 Windows 可执行文件时(例如PDFXC查看器) 在 wine 下,移动或者重命名 Windows 可执行文件是否会影响其在 wine 下的运行?
谢谢。
答案1
飞机总是在地面加油吗?
当然你会这么想。但是 0.001% 的时间它们在空中加油。例如军事应用。所以这个规则并不牢固。可执行文件和脚本也是如此。例如,病毒会在可执行文件运行时感染它们,也会感染磁盘上的副本。如果它们崩溃了,那是一件好事。但是非病毒也可以更新可执行文件/脚本。
自我更新的脚本示例
此脚本:如何让脚本在单独的文件中记录其执行的次数?根据已运行的次数进行更新。
传统上,每个脚本文件都使用一个单独的配置文件来记录其运行次数。但是,如果您有几十个脚本,则将运行次数存储在脚本本身中是有意义的。此外,您不必跟踪配置文件的存储位置,也不必在配置文件移动时更改脚本。修改运行次数的代码可以包含在或source
bash.
命令中,以降低维护成本并提高可读性。
代码片段
以下是上面链接中的相关代码:
# This script run count: 0
[ "${FLOCKER}" != "$0" ] && exec env FLOCKER="$0" flock -en "$0" "$0" "$@" || :
# This is useful boilerplate code for shell scripts. Put it at the top of
# the shell script you want to lock and it'll automatically lock itself on
# the first run. If the env var $FLOCKER is not set to the shell script
# that is being run, then execute flock and grab an exclusive non-blocking
# lock (using the script itself as the lock file) before re-execing itself
# with the right arguments. It also sets the FLOCKER env var to the right
# value so it doesn't run again.
# Read this script with entries separated newline " " into array
mapfile -t ScriptArr < "$0"
# Build search string that cannot be named
SearchStr="This script"
SearchStr=$SearchStr" run count: "
# Find our search string in array and increment count
for i in ${!ScriptArr[@]}; do
if [[ ${ScriptArr[i]} = *"$SearchStr"* ]]; then
OldCnt=$( echo ${ScriptArr[i]} | cut -d':' -f2 )
NewCnt=$(( $OldCnt + 1 ))
ScriptArr[i]=$SearchStr$NewCnt
break
fi
done
# Rewrite our script to disk with new run count
# BONUS: Date of script after writing will be last run time
printf "%s\n" "${ScriptArr[@]}" > "$0"
代码解析
我将快速解释一下独特代码部分的工作原理。
mapfile -t ScriptArr < "$0"
^ 这会将整个脚本读/script/path/script-name.sh
入名为 的数组中ScriptArr
。
OldCnt=$( echo ${ScriptArr[i]} | cut -d':' -f2 )
NewCnt=$(( $OldCnt + 1 ))
ScriptArr[i]=$SearchStr$NewCnt
^ 这将获取注释行中的旧计数:# This script run count: 0
并将其加 1。
printf "%s\n" "${ScriptArr[@]}" > "$0"
^ 这会将修改后的脚本数组作为新的可执行脚本写入磁盘。一个好的(或坏的)副作用是脚本上次运行的日期现在是脚本的修改日期。
多用户注意事项
注意FLOCKER
上面命令中的变量:
[ "${FLOCKER}" != "$0" ] && exec env FLOCKER="$0" flock -en "$0" "$0" "$@" || :
^ 这是针对多个用户的。如果一个用户正在运行脚本,它会阻止第二个用户运行同一个脚本。假设您等到第一个用户的工作结束,然后移动脚本。这很糟糕,因为处于等待模式的第二个用户现在可以访问运行脚本,因为信号量锁被丢弃了。然而,在第一个用户的工作完成后,您将脚本移动到了另一个目录。99.999% 的时间都不是大问题,但在极少数情况下,会出现无法理解的错误。
概括
正在运行的脚本或可执行文件可以改变自身,甚至可以改变同一应用程序中未运行的另一个程序。
一般来说,移动(即重命名)正在运行的程序是 99% 安全的。不过我永远不会这么做。
您的问题是关于wine
(伪 Windows)的,但这些 bash 脚本是为 Linux 下的 Ubuntu 和 Windows 下的 Ubuntu(WSL)设计的。重点不在于此,wine
而在于展示在编程/脚本世界中可以做什么。