参数编号变量不计算输入的参数

bbo*_*boy 3 bash shell-script

我有以下脚本:

echo  'Please select type file , the name of the input file and the name of the output file:

     a.plain ( please press a ) <input_file> <output_file>;
     b.complex ( please press b ) <input_file> <output_file>;'

read one two three
echo $#

if  [ $# -ne 3 ]; then
   echo "Insufficient arguments !"
   exit 1;
else
   echo "Number of passed parameters is ok"
fi
Run Code Online (Sandbox Code Playgroud)

$# 始终输出 0 ,当我稍后在脚本中使用 $one 、 $two 和 $three 时, read 命令会提供正确的变量

谢谢你。

Kus*_*nda 7

要测试是否获得了所有变量的值并否则退出,请使用-z测试来测试空字符串:

if [ -z "$one" ] || [ -z "$two" ] || [ -z "$three" ]; then
    echo 'Did not get three values' >&2
    exit 1
fi
Run Code Online (Sandbox Code Playgroud)

$#值是位置参数的数量,通常是命令行参数(或由set内置参数设置的值)。这些在$1$2$3等中可用(或在数组中共同存在"$@")并且与read内置函数读取的值无关。


使您的脚本将输入作为命令行参数而不是交互式读取它们(如果用户要提供一个或多个路径,这可能是首选,因为他们可能会利用制表符完成功能,并且还可以更容易地使用另一个脚本中的脚本,不需要连接终端),使用

if [ "$#" -ne 3 ]; then
    echo 'Did not get three command line arguments' >&2
    exit 1
fi

one=$1
two=$2
three=$3
Run Code Online (Sandbox Code Playgroud)

在这种情况下,脚本将作为

./script.sh a.plain /path/to/inputfile /path/to/outputfile
Run Code Online (Sandbox Code Playgroud)

如果输入的处理可以从标准输入发生并且输出可以发送到标准输出(即如果您实际上不需要脚本内的输入文件和输出文件的显式路径),那么脚本只有取第一个参数(a.plainb.complex)。

./script.sh a.plain </path/to/inputfile >/path/to/outputfile
Run Code Online (Sandbox Code Playgroud)

然后脚本将使用标准输入和标准输出流进行输入和输出(因此只需检查单个命令行参数)。

这将使运行脚本与从另一个程序管道输入的数据成为可能,并且它还允许进一步的后处理:

gzip -dc <file-in.gz | ./script.sh a.plain | sort | gzip -c >file-out.gz
Run Code Online (Sandbox Code Playgroud)