没有seq或jot的shell倒计时

Gra*_*ham 0 shell countdown

我正在尝试制作倒数计时器脚本,该脚本需要几秒钟$1,然后倒计时到零,显示当前剩余的秒数.

问题是,我在一个没有的嵌入式盒子上做这个,seq或者jot我知道可以生成我的数字列表的两个工具.

这是我在普通(非嵌入式)系统上工作的脚本:

#!/bin/sh

for i in $(/usr/bin/jot ${1:-10} ${1:-10} 1); do
    printf "\r%s " "$i"
    sleep 1
done

echo ""
Run Code Online (Sandbox Code Playgroud)

这适用于FreeBSD.如果我在Linux机器上,我可以用以下代码替换for:

for i in $(/usr/bin/seq ${1:-10} -1 1); do
Run Code Online (Sandbox Code Playgroud)

为了同样的效果.

但如果我没有jotOR,我该怎么办seq

Mar*_*eed 5

"香草"Bourne shell的问题在于没有这样的东西; 行为取决于具体的实施.大多数现代设备/bin/sh都具有POSIX功能,但细节不同.当我进入"sh兼容"模式时,我有一种回归真正古老的Bourne功能的习惯,这种模式在30年前很有用,但在现代系统甚至是嵌入式系统上通常都是过度的.:)

无论如何,这是一个通用的倒计时循环,即使在非常旧的shell中也可以工作,但在现代bash/dash/ksh/zsh/etc中仍能正常工作.它确实需要expr命令,这是一个非常安全的要求.

i=10
while [ $i -gt 0 ]; do
  ...
  i=`expr $i - 1`
done
Run Code Online (Sandbox Code Playgroud)

因此,如果您的嵌入式系统具有printf相同的"默认为10,如果没有指定参数"行为:

#!/bin/sh
n=$1
i=${n-10}
while [ $i -gt 0 ]; do
  printf '\r%s ' "$i"
  i=`expr $i - 1`
  sleep 1
done
Run Code Online (Sandbox Code Playgroud)

(前两行可能只是替换i=${1-10},但有些 - 再次,古代 - shell不喜欢将特殊参数扩展应用于数字参数.)

如果系统具备printf的话,那就有问题; 只有shell的内置echo(或没有内置和一些随机选择的实现/bin/echo),没有保证的方法来做这些事情(回显特殊字符或阻止换行).您可以使用\r\015获得回车.您可能需要-e让shell识别这些(但这可能最终会回显文字-e).在脚本中放置文字回车可能会起作用,但会使脚本难以维护.

同样,-n可能压缩换行符,但可能只是回显一个字面值-n.echo使用新线\c自然会出现的特殊序列来压缩新线的最早方式; 这仍适用于某些版本/bin/echo(包括Mac OS X上的版本)或与bash的内置echo -e选项一起使用.

因此,似乎是脚本中最简单的部分可能是让您触及的部分awk.

  • @Graham - 我们不知道你有什么系统.仅仅因为他们碰巧没有对其进行操作而低估每个人的答案是很粗鲁的,特别是当我在答案中说回声可能不起作用时.`echo ...\c`是你如何在某些系统上执行no-newlines(它甚至可以在OS X上使用`/ bin/echo`).八进制回车在黑暗中是一个摆动,但它似乎比'\ r'更有效.如果你有办法在文字中加入文字CR,那可能是最好的. (2认同)