Shell命令显示不同的行为..终端与运行Scipt

时间:2019-08-10 16:29:57

标签: linux bash shell

当我直接通过终端运行命令时,却获得了所需的输出。但是,当我为同一脚本创建脚本时,它无法正常工作。

基本上,我是使用sed命令替换文件中字符串的所有实例。

我是bash脚本的新手,我试图在脚本中进行所有可能的更改,但是我没有得到适当的结果。

为了避免这种差异,我需要了解什么?我在这里想念什么? 为什么不只是简单地将命令从终端复制到具有相同行为的脚本?

下面是我直接通过终端运行的内容:

sed -i 's,'"^${var}"','"$change"',gI' ./filename 
sed -i 's,'" ${var}"','" $change',gI' ./filename 

这是我的剧本:

change="someotherstring"
while read -r line
do
    sed -i 's/'" $line"'/'" $change"'/gI' filename  
    sed -i 's/'"^$line"'/'"$change"'/gI' filename
done < "$2" #file_from_which_i'm_picking_strings_to_replace

通过终端运行命令时,我可以替换所有可能的目标字符串。

但是,在脚本上,同一命令的行为有所不同,不会替换可能的候选对象,或者不会产生异常结果。

2 个答案:

答案 0 :(得分:0)

嗯,我看不出您的脚本的行为有任何不同的任何原因。我认为您的问题可能与如何调用它有关,或者与当前目录在调用时有关。不过,有两个建议。

您应该在脚本中特别提到外壳程序,我们可以简化引用:

#!/bin/sh
change=someotherstring
while read -r line
do
    sed -i "s/ $line/ $change/gI" filename  
    sed -i "s/^$line/$change/gI" filename
done < "$2" # file of strings to replace

我看不到

sed -i "s/ $line/ $change/gI" filename  

可以。您只读了$line;第一个字符前面不能有任何开头的空格。因此,仅第二行有效。 (如果要使用多个sed命令,则可以多次使用其-e选项,或使用“;”将命令分隔在单个字符串中。)

如果单词列表很长,您会发现先使用sed生成sed命令,然后立即针对所有目标使用该文件会更有效。大致:

#! /bin/sh
set -e
change="$1"
words="$2"
shift 2
sed -E "s:.+:s/&/$change/:" "$words" > "$words.sed"
sed -E -f "$words.sed" $@

这还具有将sed命令显示在文件中的好处,您可以在其中检查执行它们之前(或之后)的命令。否则,您必须非常确定自己的shell转换。

我习惯性地将set -e用作我的shell脚本的第二行。如果遇到错误,除非明确处理,否则我希望它停止。

最后,别忘了您可以使用 sh -x脚本名称来查看脚本的评估方式。

答案 1 :(得分:0)

我在行为上与标题类似,因此在寻找答案时遇到了这个问题。

如果一个类似的经验不足的人到这里来,因为他们不知道如何描述和搜索他们的问题,我将分享我的经验,并向那些读者指出可以帮助他们进行故障排除的方向

我遇到的异常行为是将ssh终端中执行命令的结果与通过ssh远程执行脚本的结果进行比较。最终有两个因素起作用。

  1. 在这两个实例中,$ PATH变量的设置不同。 ssh终端是一个交互式外壳,而远程执行的脚本是一个非交互式外壳。此外,登录外壳程序和非登录外壳程序之间也有区别。

我对这些组合之间的所有细微差别的了解很少,因为这是我第一次接触它们,但是我最终不得不向PATH添加位置以使脚本像在交互式shell中一样运行脚本。

  1. 变量分配。远程执行脚本中的$ PATH由本地计算机(我的笔记本电脑)的PATH填充。为了在远程计算机上使用$ PATH或任何变量,脚本中的$需要这样转义\ $ PATH。

因为本地计算机的$ PATH和交互式终端窗口中的$ PATH非常相似,所以我花了很长时间才意识到我没有在脚本中看到\ $ PATH值,以为我是。由于我也没有意识到整个脚本中的$ VARiables分配都不是\ $ VARiables,所以这种监督变得更加复杂。这导致了非常异常和意外的结果,这使我进入了此页面。

尽管不是原始问题的明确解决方案,但我希望这将有助于其他人因标题的含糊性质而引诱到这里。