我正在尝试自动化物理应用程序的扫描过程。我的脚本是
#!/bin/bash
i=1
file="ATLASbins.txt"
while IFS= read line
do
scan=$line
cat test.sh | sed "s/ set vchi 5000/ set vchi $scan/g" > test2.sh
chmod +x test2.sh
bash -x /home/mario/Mine/test2.sh
i=$((i + 1))
done <"$file"
其中 test2.sh 是另一个脚本,我在其中启动进行扫描的应用程序。第二个脚本中的内容示例如下
#!/bin/bash
/home/mario/mg5/bin/mg5_aMC
"import model Implementation"
"generate u++ > l+ l+"
output firstscript$i
set vchi 6500
launch firstscript$i
其中“导入模型”、“输出”和“启动”是应用程序的命令(在终端中运行)。
发生的情况是命令(应用程序内部)不起作用,我得到类似的行
PATH/test2.sh:第 5 行:导入模型实现:未找到命令
我不知道如何执行此操作(即编写一个可以将命令写入应用程序的脚本),并尝试了各种不同的分隔符,在不同的 shell 中运行 test2 脚本并使用终端在新终端中调用它 -侏儒。我怎样才能做到这一点?
另一个观察结果是我需要将 i 的变量值写入应用程序内部。我尝试这样写,例如“输出firstscript$i”,我想即使命令有效,它也不会起作用。
答案1
由于您test2.sh
作为单独的 shell 脚本运行,因此 shell 变量i
在其中不可用。这意味着脚本中的扩展$i
将为空test2.sh
。您可以通过两种方式解决这个问题:
在第一个脚本中创建
i
一个环境变量。export i
这很方便,但在一般情况下并不是一个好的解决方案,因为其他脚本可能很想使用自己的i
变量,该变量可能独立于调用脚本中变量的值。调用脚本时在脚本
$i
的命令行上给出: 。这将使访问as (第一个命令行参数)中的值成为可能。test2.sh
test2.sh "$i"
$i
test2.sh
"$1"
第二个问题是您的mg5_aMC
程序期望获得输入,即您在脚本中列出的命令。但是您输入这些内容的方式test2.sh
意味着它们将被视为外壳命令。脚本中没有任何内容将特殊控制命令传递给程序。
正如您从收到的错误中看到的那样,是 shell 抱怨找不到命令。它们不是 shell 命令,因此(当您知道如何解释事物时)这并不奇怪。
假设您的mg5_aMC
程序从标准输入读取,我不会为程序的每次运行编写 shell 脚本,而是为其提供一个输入控制/命令文件:
#!/bin/bash
file="ATLASbins.txt"
i=1
while IFS= read -r scan
do
sed -e "s/@scan@/$scan/" \
-e "s/@i@/$i/" \
input-template.in >input.in
/home/mario/mg5/bin/mg5_aMC <input.in
i=$((i + 1))
done <"$file"
在这里,该文件input-template.in
可能看起来像这样
"import model Implementation"
"generate u++ > l+ l+"
output firstscript@i@
set vchi @scan@
launch firstscript@i@
我选择将其用于@thing@
将替换为sed
shell 脚本中的调用的内容。
这假设 的值$scan
不包含会干扰sed
命令的字符(例如/
)。
如果您的程序的控制脚本相当短,另一种方法是使用“here-document”将控制命令输入到您的程序中:
#!/bin/bash
file="ATLASbins.txt"
i=1
while IFS= read -r scan
do
/home/mario/mg5/bin/mg5_aMC <<END_INPUT
"import model Implementation"
"generate u++ > l+ l+"
output firstscript$i
set vchi $scan
launch firstscript$i
END_INPUT
i=$((i + 1))
done <"$file"
这里文档基本上是一种对一段文本进行重定向的类型,该文本不是在文件中给出的,而是在<<TAG
和 结尾之间给出的TAG
。文本中的变量(如果按上面的方式编写)将在输入到命令之前由 shell 扩展。