我在shell(bash)脚本中有这个代码,用于将文件拆分成更小的部分:
for (( i=$start; i<=$lineCount; i=i+$interval))
do
temp=`expr $i + $interval`;
if [ $temp -le $lineCount ]
then
command="head -$temp $fileName | tail -$interval > $tmpFileName";
echo "Creating Temp File: $command";
else
lastLines=`expr $lineCount - $i`;
command="head -$temp $fileName | tail -$lastLines > tmpFileName";
echo "Creating Temp File: $command";
fi
`$command`;
done
它在stdin上打印以下输出:
Creating Temp File: head -10 tmp.txt | tail -10 > tmp.txt_TMP
head: invalid trailing option -- 1
Try `head --help' for more information.
但打印的命令:head -10 tmp.txt | tail -10 > tmp.txt_TMP
在命令行上运行正确。
我做错了什么?
答案 0 :(得分:1)
当您将管道|
放入变量时,shell会将其解释为普通字符而不是管道。同样适用于>
,<
,...
一种丑陋的方式是使用eval
。
更好的方法是将命令拆分为不同的部分,以便除去管道和重定向操作符。
例如:
command="head -$temp $fileName | tail -$lastLines > tmpFileName";
将写成:
cmd1="head -$temp $fileName";
cmd2="tail -$lastLines";
执行并说:
"$cmd1" | "$cmd2" > tmpFileName;
此外,您不需要反引号来执行存储在变量中的命令。简单地说:
$command
答案 1 :(得分:1)
问题出在这里:
command="head -$temp $fileName | tail -$interval > $tmpFileName"
以后:
`$command`
不是将整个管道命令存储在字符串中,而是直接执行命令:
head -$temp "$fileName" | tail -$interval > "$tmpFileName"
答案 2 :(得分:0)
这里有几个问题。首先,让我们看看我们的重构版本是否有正确的引用和许多其他改进:
for (( i=start; i<=lineCount; i+=interval)); do
((temp = i + interval))
if (( temp <= lineCount )); then
echo "Creating Temp File using 'tail -n $interval'"
head -n "$temp" "$fileName" | tail -n "$interval" > "$tmpFileName"
else
((lastLines = lineCount - i))
echo "Creating Temp File using 'tail -n $lastLines'"
head -n "$temp" "$fileName" | tail -n "$lastLines" > "$tmpFileName"
fi
done
我已将所有算术表达式更改为correct syntax。这就是你想要的,因为它更具可读性
然后,似乎您想将命令放入变量然后运行它。简而言之,你根本就不应该这样做。 Here's why
此外,这不是c ++,您不必在每一行都放置;
您在代码的第10行的$
中错过了tmpFileName
个字符。