Shell脚本错误:“head:无效尾随选项 - 1”

时间:2013-12-20 11:04:56

标签: linux bash

我在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在命令行上运行正确。

我做错了什么?

3 个答案:

答案 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个字符。