到目前为止,您已经了解了如何编写无需用户输入即可完成工作的 Linux bash 脚本。今天我们将继续我们的 Linux bash 脚本系列。
如果您想了解我们在谈论什么,我建议您查看之前的帖子。
Bash 脚本基础知识
Bash 脚本 – For 循环
今天我们将知道如何检索用户的输入并处理该输入,以便我们的脚本变得更具交互性。
要将数据传递到 shell 脚本,您应该使用命令行参数。
$ ./myscript 3 5
这里我们向脚本发送两个参数(3 和 5)。那么如何在我们的bash脚本中读取这些参数呢?
读取参数
shell 为您提供了一些易于使用的变量来处理输入参数:
- $0 是脚本的名称。
- $1 是第一个参数。
- $2 是第二个参数。
shell可以读取第9个参数,即$9。
让我们看看这些变量的作用:
#!/bin/bash
echo $0 # Script name
echo $1 # 1st parameter
echo $2 # 2nd parameter
echo $3 # 3rd parameter
检查以下命令的结果:
./myscript 5 10 15
这是我们如何使用两个参数并计算它们之和的另一个示例。
#!/bin/bash
total=$(( $1 + $2 ))
echo First passed parameter is $1.
echo Second passed parameter is $2.
echo Total is $total.
$ ./myscript 5 10
参数不限于数字;它们可以是这样的字符串:
#!/bin/bash
echo Hello $1, how do you do
./myscript Adam
结果正如预期的那样。
如果我们的参数包含空格,并且我们想将其作为一个值传递怎么办?我想你从之前的帖子中就知道答案了。答案是使用引号。
如果您的脚本需要超过九个参数,则应使用像 ${10} 这样的大括号。
检查参数
如果您不传递参数并且您的代码需要它,您的脚本将因错误而退出。
这就是为什么我们应该使用Linux if 语句以确保它们存在。
#!/bin/bash
if [ -n "$1" ]; then # If first parameter passed then print Hi
echo Hi $1.
else
echo "No parameters found. "
fi
计数参数
要获取传递的参数数量,可以使用此变量 ($#)。
#!/bin/bash
echo There were $# parameters passed.
./myscript 1 2 3 4 5
Linux bash 脚本有多优秀?该变量还提供了一种获取最后一个参数的极客方式。看看这个技巧:
#!/bin/bash
echo Last passed parameter is ${!#}
迭代参数
$* 变量将所有参数保存为一个值。
$@ 变量将所有参数保存为单独的值,以便您可以迭代它们。
此代码展示了如何使用它们:
#!/bin/bash
echo "The first variable \$* method: $*"
echo "-----------"
echo "The second variable \$@ method: $@"
结果相同,但如果您想了解差异,请查看以下示例:
#!/bin/bash
total=1
for var in "$*"; do
echo "\$* =======> #$total = $var"
total=$(($total + 1))
done
total=1
for var in "$@"; do
echo "\$@ =======> #$total = $var"
total=$(($total + 1))
done
检查结果以查看差异:
结果很清楚。您可以根据需要使用任何方法。
移动参数变量
shift 命令将每个参数变量向左移动:
变量 $3 ==> 变量 $2。
变量 $2 ==> 变量 $1。
变量 $1 ==> 被删除。
变量 $0 ==> (脚本名称)原样。
您可以使用 shift 命令迭代参数,如下所示:
#!/bin/bash
total=1
while [ -n "$1" ]; do # while loop starts
echo "#$total = $1"
total=$(($total + 1))
shift
done
在这里,我们有一个while 循环检查 1 美元长度。如果 $1 变为零,则循环停止。移位命令将所有传递的参数向左移动。
使用shift命令时要小心,因为你无法恢复移位后的参数。
Bash 脚本选项
选项是单个字母,前面有一个破折号。
#!/bin/bash
while [ -n "$1" ]; do # while loop starts
case "$1" in
-a) echo "-a option passed" ;; # Message for -a option
-b) echo "-b option passed" ;; # Message for -b option
-c) echo "-c option passed" ;; # Message for -c option
*) echo "Option $1 not recognized" ;; # In case you typed a different option other than a,b,c
esac
shift
done
$ ./myscript -op1 -op2 -op3 -op4
上面的代码检查正确的选项之一。如果您键入其中之一,就会运行合适的命令。
将选项与参数分开
有时您需要在同一脚本中使用选项和参数。你必须把它们分开。通过这样做,您可以告诉 bash 参数在哪里以及选项在哪里。
我们在选项列表的末尾使用双破折号 (-)。 shell 看到双破折号后,会将其余输入视为参数而不是选项。
#!/bin/bash
while [ -n "$1" ]; do # while loop starts
case "$1" in
-a) echo "-a option passed" ;; # Message for -a option
-b) echo "-b option passed" ;; # Message for -b option
-c) echo "-c option passed" ;; # Message for -c option
--)
shift # The double dash which separates options from parameters
break
;; # Exit the loop using break command
*) echo "Option $1 not recognized" ;;
esac
shift
done
total=1
for param in $@; do
echo "#$total: $param"
total=$(($total + 1))
done
$ ./myscript -a -b -c -- 5 10 15
从结果中可以看到,双破折号后面的所有参数都被视为参数而不是选项。
处理带有值的选项
当您深入研究 Linux bash 脚本时,有时您需要带有附加参数值的选项,如下所示:
./myscript -a value1 -b -c value2
应该有一种方法来识别选项的任何附加参数并能够处理它。
#!/bin/bash
while [ -n "$1" ]; do # while loop starts
case "$1" in
-a) echo "-a option passed" ;;
-b)
param="$2"
echo "-b option passed, with value $param"
shift
;;
-c) echo "-c option passed" ;;
--)
shift # The double dash makes them parameters
break
;;
*) echo "Option $1 not recognized" ;;
esac
shift
done
total=1
for param in "$@"; do
echo "#$total: $param"
total=$(($total + 1))
done
如果我们使用以下选项运行它:
$ ./myscript -a -b test1 -d
从结果中,您可以看到我们使用 $2 变量获取 -b 选项的参数。
标准选项
当您开始编写 Linux bash 脚本时,您可以自由选择适合您的选项的字母。
然而,有些字母在Linux程序中是常用的。
这是常用选项的列表:
-a |
List all items. |
-c |
Get the count of items. |
-d |
Output directory. |
-e |
Expand items. |
-f |
To specify a file. |
-h |
To show the help page. |
-i |
To ignore character case. |
-l |
To list a text. |
-n |
To say no for a question. |
-o |
To send output to a file or so. |
-q |
Keep silent; don’t ask the user. |
-r |
To process something recursively. |
-s |
Stealth mode. |
-v |
Verbose mode. |
-x |
Specify executable. |
-y |
To say yes without prompting the user. |
遵守标准是件好事。如果您使用 Linux,您可能会觉得其中许多选项很熟悉。
使用 read 命令获取用户输入
有时,当 bash 脚本运行时,您需要来自用户的数据。
bash shell 使用 read 命令来实现此目的。
read 命令从标准输入(键盘)或文件描述符读取输入并将其存储在变量中:
#!/bin/bash
echo -n "What's your name: "
read name
echo "Hi $name,"
我们使用 -n 选项禁用换行符,以便您可以在同一行中键入文本。
您可以像这样指定多个输入:
#!/bin/bash
read -p "What's your name: " first last
echo "Your data for $last, $first…"
如果您没有为读取命令指定变量,它将把所有传入的输入保存在 REPLY 变量中。
#!/bin/bash
read -p "What's your name: "
echo Hello $REPLY,.
您可以使用 -t 选项指定输入超时(以秒为单位)。
#!/bin/bash
if read -t 5 -p "What's your name: " name; then
echo "Hi $name, how are you?"
else
echo "You took much time!"
fi
如果五秒钟内没有输入数据,脚本将执行 else 子句并打印一条抱歉消息。
读取密码
在 Linux bash 脚本中,有时,您不希望用户输入显示在屏幕上,例如输入密码。
-s 选项禁止输出出现在屏幕上。
#!/bin/bash
read -s -p "Enter password: " mypass
echo "Your password is $mypass? "
读取文件
read 命令可以在每次调用时读取文件一行。
现在,如果您想获取所有文件数据,可以使用 cat 命令获取内容,然后使用 while 循环将其发送到 read 命令,如下所示:
#!/bin/bash
count=1
# Get file content then pass to read command by iterating over lines using while command
cat myfile | while read line; do
echo "#$count: $line"
count=$(($count + 1))
done
echo "Finished"
或者我们可以通过将文件内容重定向到 while 循环来使其更简单,如下所示:
#!/bin/bash
while read line; do
echo $line
done <myfile
我们只需将文件内容传递给 while 循环并迭代每一行并打印行号和内容,每次将计数增加 1。
我希望你觉得这篇文章很有趣。继续回来。
谢谢。