我非常非常熟悉Linux(来自Windows)并试图编写一个我希望可以在多个系统上执行的脚本。我尝试使用Python,但也很难。以下是我到目前为止的情况:
cd /bin
bash
source compilervars.sh intel64
cd ~
exit #exit bash
file= "~/a.out"
if[! -f "$file"]
then
icc code.c
fi
#run some commands here...
脚本挂在第二行(bash)。我不确定如何解决这个问题,或者我是否做错了。请指教。
此外,有关如何在同一网络上的多个系统上运行此脚本的任何提示?
非常感谢。
答案 0 :(得分:2)
我相信你想做的事情:
#!/bin/bash
source /bin/compilervars.sh intel64
file="$HOME/a.out"
if [ ! -f "$file" ]; then
icc code.c
fi
您可以将其放在一个文件中,并使其chmod +x myscript
可执行。然后,您将使用./myscript
运行它。或者,您可以使用bash myscript
运行它。
你的脚本没什么意义。第二行将打开一个新的bash
会话,但它会一直坐在那里直到退出它。此外,很少需要来回更改目录。要在另一个目录中执行单个命令,通常会执行
( cd /other/place && mycommand )
( ... )
告诉shell你想在子shell中执行此操作。 cd
发生在该子shell中,并且在完成后不需要cd
。如果cd
失败,则不会运行该命令。
例如:您可能希望在编译代码时确保您在$HOME
中:
if [ ! -f "$file" ]; then
( cd $HOME && icc code.c )
fi
...甚至从变量file
中挑出目录名并使用:
if [ -f "$file" ]; then
( cd $(dirname "$file") && icc code.c )
fi
分配给变量需要在我编写时发生,=
周围没有空格。
同样,需要在if
之后和[ ... ]
之内的空格,就像我在上面写的那样。
我还倾向于在脚本中使用$HOME
而不是~
,因为它更具描述性。
答案 1 :(得分:1)
shell脚本不是键入终端的击键记录。如果您编写如下脚本:
command1
bash
command2
这并不意味着脚本将切换到bash,然后在不同的shell中执行command2
。这意味着将运行bash
。如果有一个控制终端,那个bash会显示一个提示并等待输入一个命令。你必须输入exit
才能退出该bash。只有这样,原始脚本才会继续command2
。
无法将脚本中途切换到其他shell。有办法模拟这个。脚本可以使用不同的shell重新执行自身。为了做到这一点,脚本必须包含逻辑来检测它是否被重新执行,以便它可以防止再次重新执行自己,并跳过一些不应该运行两次的代码。
在this script中,我实施了这样的重新执行黑客攻击。它由以下几行组成:
#
# The #!/bin/sh might be some legacy piece of crap,
# not even up to 1990 POSIX.2 spec. So the first step
# is to look for a better shell in some known places
# and re-execute ourselves with that interpreter.
#
if test x$txr_shell = x ; then
for shell in /bin/bash /usr/bin/bash /usr/xpg4/bin/sh ; do
if test -x $shell ; then
txr_shell=$shell
break
fi
done
if test x$txr_shell = x ; then
echo "No known POSIX shell found: falling back on /bin/sh, which may not work"
txr_shell=/bin/sh
fi
export txr_shell
exec $txr_shell $0 ${@+"$@"}
fi
txr_shell
变量(不是标准变量,我的发明)是这个逻辑检测到它被重新执行的方式。如果变量不存在则这是原始执行。当我们重新执行export txr_shell
时,重新执行的实例将具有此环境变量。
该变量还包含shell的路径;稍后在脚本中使用;它作为Makefile
变量传递给SHELL
,因此make build配方使用相同的shell。在上面的逻辑中,txr_shell
的内容无关紧要;它被用作布尔值:它是存在还是不存在。
上面代码片段中的编程风格是故意编码的,适用于非常旧的shell。这就是使用test x$txr_shell = x
代替现代语法[ -z "$txr_shell" ]
的原因,以及为什么使用${@+"$@"}
而不仅仅是"$@"
。
此脚本之后不再使用此样式,因为 由于重新执行技巧,脚本的其余部分运行在一些优秀的,相当现代的shell中。