【问题标题】:UNIX Shell Scripting OutputUNIX Shell 脚本输出
【发布时间】:2013-10-26 20:15:28
【问题描述】:

我正在尝试编写一个 shell 脚本“echo.by”,它会根据用户的选择多次回显其参数。例如,如果用户输入命令行

echo.by 5 Play it again, Sam. <return> 

脚本应该打印出来

Play it again, Sam. 
Play it again, Sam. 
Play it again, Sam. 
Play it again, Sam. 
Play it again, Sam. 

但是,我不知道如何仅打印再次播放,Sam 并排除第一个参数。 $* 命令打印所有内容,所以我最终得到了

5 Play it again, Sam. 
5 Play it again, Sam. 
5 Play it again, Sam. 
5 Play it again, Sam. 
5 Play it again, Sam. 

我的脚本需要能够容纳第一个数字之后的任何脚本,所以我不能只告诉 shell 回显$2 $3 $4 $5

这是我的脚本:

count = 0 
while test $count -lt $1 
do 
echo $* 
count = `expr $count + 1` 
done

【问题讨论】:

  • 仅供参考 -- count = 0 正在运行程序 count,参数为 =0。如果你想做一个作业,你需要省略空格:count=0。此外,((count++))count=$(( count + 1 )) 更容易编写(同样,= 周围不允许有空格)。
  • ...还有——引号;使用它们。 echo "$*",不是echo $*。如果有人在您的参数中传递了一个带引号的“*”,您不希望它被当前目录中的文件列表替换,对吗?猜猜如果你不引用你的论点会发生什么......

标签: shell unix


【解决方案1】:

只需将$1 放入稍后将引用的变量中,然后将shift 添加到脚本顶部。

【讨论】:

  • 就正确性而言,这可能是这里最好的答案。考虑添加代码示例?
【解决方案2】:

尝试使用 C 风格的循环 数组切片

#!/bin/bash

for ((i=0; i<$1; i++)); do
    echo "${@:2:${#@}}"
done

【讨论】:

    【解决方案3】:
     #!/bin/bash
     times="$1"
     shift
     for f in $(seq "$times"); do
         echo "$@"
     done
    

    编辑:按照@Charles Duffy 的建议,将$times 更改为小写。为了更好地与其他 POSIX(-like) 系统兼容,您可能需要更改循环以使用 C 风格的 for-syntax。 seq 命令在 NetBSD、FreeBSD 和 GNU 系统中可用。

    【讨论】:

    • seq 不是 POSIX 标准工具。最好使用 C 风格的 for 循环,因为您已经指定了 bash 而不是 POSIX sh。 for ((i=0; i&lt;$1; i++)); do ...
    • 相应编辑。 (也改为小写变量名——按照惯例,应该为环境变量和内置变量保留全大写以避免命名空间冲突)。
    • 正如我所说:我喜欢你的建议,但故意不改变我的答案。实现相同目标的方法不止一种,我认为您的更改更改是“编辑”的主要方式。我建议提交您自己的答案。因此,我会回滚。
    • ...顺便说一句,您缺少in;应该是for f in ...
    • 确实,忘记了in。谢谢!!
    【解决方案4】:
    #!/bin/bash
    times="$1"
    shift
    for ((f=0; f<times; i++)); do
        printf '%s\n' "$*"
    done
    

    【讨论】:

    • 为什么使用printf 和格式化字符串而不是简单的echo 输入会有开销?
    • @AdamLiss printf 不是开销——它是一个内置的 shell,和 echo 一样;它与 echo 相比的优势(除了格式字符串提供的灵活性之外)是跨平台的行为更加一致——POSIX 在 echo 是否接受选项方面是模棱两可的,而 printf 在所有平台上的行为方式都相同。
    • @AdamLiss ...对于echo 会做错事的具体示例,请考虑echo.by 5 -nprintf 版本将正确打印-n 五次; echo 版本将在选择实现 echo -n 的系统上不打印任何内容。