Shell 输入输出

本文最后更新于:2024年3月18日 凌晨

Shell 输入输出

echo

Shell 的 echo 指令与 PHP 的 echo 指令类似,都是用于字符串的输出,命令格式:

1
echo string

显示普通字符串

1
echo "It is a test"
  • 这里的双引号完全可以省略,以下命令与上面实例效果一致:
1
echo It is a test

显示转义字符

1
echo "\"It is a test\""
  • 结果将是:
1
"It is a test"
  • 同样,双引号也可以省略。

显示变量

  • read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量。
1
2
3
#!/bin/sh
read name
echo "$name It is a test"
  • 以上代码保存为 test.sh,name 接收标准输入的变量,结果将是:
1
2
3
sh test.sh
OK #标准输入。
OK It is a test #输出。

显示换行

1
2
echo -e "OK! \n"
echo "It is a test"
  • -e:开启转义。
  • 输出结果。
1
2
3
OK!

It is a test

显示不换行

1
2
3
#!/bin/sh
echo -e "OK! \c"
echo "It is a test"
  • \c:不换行。
  • 输出结果:
1
OK! It is a test

显示结果定向至文件

1
echo "It is a test" > myfile

原样输出字符串,不进行转义或取变量(用单引号)

1
echo '$name\"'
  • 输出结果:
1
$name\"

显示命令执行结果

1
echo `date`
  • 注意 这里使用的是反引号,而不是单引号。
  • 结果将显示当前日期。
1
Thu Jul 24 10:08:46 CST 2014

printf

  • printf 命令模仿 C 程序库(library)里的 printf()程序。
  • printf 由 POSIX 标准所定义,因此使用 printf 的脚本比使用 echo 移植性好。
  • printf 使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,还可以制定字符串的宽度,左右对齐方式等,默认 printf 不会像 echo 自动添加换行符,可以手动添加 \n
  • printf 命令的语法:
1
printf  format-string  [arguments...]

参数说明

  • format-string:为格式控制字符串,单引号与双引号效果一样,没有引号也可以输出。

  • arguments:为参数列表。

    • 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用。
    1
    2
    3
    4
    printf "%s\n" abc def

    abc
    def
    • 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替。

实例

1
2
3
4
printf "%-10s %-8s %-4s\n" 姓名性别体重kg
printf "%-10s %-8s %-4.2f\n" 郭靖男 66.1234
printf "%-10s %-8s %-4.2f\n" 杨过男 48.6543
printf "%-10s %-8s %-4.2f\n" 郭芙女 47.9876
  • 执行脚本,输出结果如下所示:
1
2
3
4
姓名性别体重kg
郭靖男 66.12
杨过男 48.65
郭芙女 47.99
  • %s %c %d %f 都是格式替代符,%s 输出一个字符串,%d 整型输出,%c 输出一个字符,%f 输出实数,以小数形式输出。
  • %-10s 指一个宽度为 10 个字符(- 表示左对齐,没有则表示右对齐),任何字符都会被显示在 10 个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
  • %-4.2f 指格式化为小数,其中 .2 指保留2位小数。

printf 的转义序列

序列 说明
\a 警告字符,通常为ASCII的BEL字符
\b 后退
\c 抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符,任何接下来的参数以及任何留在格式字符串中的字符,都被忽略
\f 换页(formfeed)
\n 换行
\r 回车(Carriage return)
\t 水平制表符
\v 垂直制表符
\ 一个字面上的反斜杠字符
\ddd 表示1到3位数八进制值的字符,仅在格式字符串中有效
\0ddd 表示1到3位的八进制值字符

read

  • 在shell脚本中,使用read命令获取命令行输入。
1
read ${variable}
  • -p:指定提示语句。
  • -n:限定字符个数。
  • -t:设置等待时间)
  • -s:不显示。

基本读取

  • read命令接收标准输入(键盘)的输入,或者其他文件描述符的输入,在得到输入之后,read命令把输入数据放入一个标准变量中,下面是read命令的基本形式:
1
2
3
4
5
6
# !/bin/bash                                 # 指定shell类型

echo -n "Enter your name:" # 参数-n的作用是不换行,echo默认换行。
read name # 把键盘输入放入变量name
echo "hello $name,welcome to my program" # 显示输入信息。
exit 0 # 返回一个零退出状态,退出shell程序。
  • 由于read命令提供了-p参数,允许在read命令行中直接指定一个提示语句,所以上面的脚本可以简写成下面的形式:
1
2
3
4
# !/bin/bash                                 # 指定shell类型

read -p "Enter your name:" name # 参数-p指定一个提示语句,并把键盘输入放入变量name
echo "hello $name, welcome to my program" # 显示输入信息。
  • 上例中,read后面的变量只有name一个,实际上可以有多个,如果有多个输入数据,则应指定多个变量,这样第一个数据赋给第一个变量,第二个数据赋给第二个变量…
1
2
3
4
# !/bin/bash                # 指定shell类型

read -p "Enter your name age id_card address:" name age id_card address # 通过参数-p指定一个提示语句,并把键盘输入放入变量name
echo "hello $name $age $id_card $address , welcome to my program"
  • 如果输入数据个数过多,远大于变量个数,则多余的所有数据都给最后一个变量,如果输入数据太少,不会结束。
1
2
3
4
5
6
# !/bin/bash                # 指定shell类型

read -p "Enter your name age id_card address:" name age id_card address
echo "hello $address , welcome to my program"

# 多输入几个值,多余的值给最后一个变量
  • 如果不指定变量名,那么read命令把接收到的输入放在环境变量REPLY中,例如read -p "Enter a number",环境变量REPLY中包含输入的所有数据,在shell脚本中,我们可以正常使用环境变量REPLY

输入计时,输入计数

  • 使用read命令有潜在危险,脚本很可能停下来一直等待用户输入,因此,我们可以使用-t选项指定一个计时器,设置等待输入的秒数,当计时器满时,read命令返回一个非零退出状态。
1
2
3
4
5
6
7
8
9
10
# !/bin/bash                                      # 指定shell类型

# 设置用户输入超时及处理方法

if read -t 5 -p "please enter your name:" name # -t,设置输入超时时间(本语句设置超时时间为5秒),默认单位是秒,-p,指定输入提示。
then # 如果不超过5秒。
echo "hello $name ,welcome to my script"
else # 超过5秒。
echo "Timeout"
fi
  • read命令除了可以设置输入计时,还可以设置输入计数,当输入的字符数目达到设定数目时,自动退出,并把输入数据赋给变量。
1
2
3
4
5
6
7
8
9
10
11
# !/bin/bash          # 指定shell类型

read -n2 -p "Do you want to continue [Y/N]?" answer
case $answer in
(Y | y)
echo "fine, continue";;
(N | n)
echo "ok, good bye";;
(*)
echo "error choice";;
esac
  • 该例子使用了-n选项,后接数值1,只要按下1个字符进行回答,无需按回车键,read命令立即接受输入并将其传给变量,如果输入的字符个数小于-n选项数值,我们就需要按回车键。

默读(输入不显示在监视器上)

  • 有时,脚本需要用户输入,但用户不希望输入数据显示在监视器上,典型的例子就是输入密码,当然还有很多其他需要隐藏的数据,-s选项能够使read命令中的输入数据不显示在监视器上(实际上,数据是显示的,只是read命令把文本颜色设置成与背景相同)
1
2
3
4
5
6
7
# !/bin/bash                               # 指定shell类型

# 默读(输入不显示在监视器上,如读取隐藏数据,用户密码)

read -s -p "Enter your password:" passwd
echo # read默认不换行,echo用于换行。
echo "your password is $passwd"

从文件读取输入

  • 最后,我们还可以使用read命令读取Linux系统上的文件,每次调用read命令都会读取文件中的”一行"文本,当文件没有可读行时,read命令以非零状态退出。
1
2
3
4
5
6
7
8
9
10
# !/bin/bash                       # 指定shell类型

exec 0< TimeOut.sh
count=1 # 赋值语句,不加空格。

while read line # read读到的值放在line中。
do
echo "Line $count:$line"
count=$[ $count + 1 ] # 注意中括号中的空格。
done
  • 读取文件的关键是如何把文本中的数据传送给read命令,最常用的方法是对文件使用cat命令,然后通过管道,把结果直接传送给包含read的while命令。
1
2
3
4
5
6
7
8
9
# !/bin/bash                      # 指定shell类型

count=1 # 赋值语句,不加空格。

cat Timeout.sh | while read line # cat命令查看文件Timeout.sh,然后管道给read命令,作为read的输入,read读到的值放在line中
do # while循环。
echo "Line $count:$line"
count=$[ $count + 1 ] # 注意中括号中的空格。
done

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!