Linux Bash 脚本编写第 3 部分 – 参数和选项

2023-10-25

到目前为止,您已经了解了如何编写无需用户输入即可完成工作的 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。

我希望你觉得这篇文章很有趣。继续回来。

谢谢。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux Bash 脚本编写第 3 部分 – 参数和选项 的相关文章

  • 子目录中的头文件(例如 gtk/gtk.h 与 gtk-2.0/gtk/gtk.h)

    我正在尝试使用 GTK 构建一个 hello world 其中包括以下行 include
  • 监控子进程的内存使用情况

    我有一个 Linux 守护进程 它分叉几个子进程并监视它们是否崩溃 根据需要重新启动 如果父进程可以监视子进程的内存使用情况 以检测内存泄漏并在超出一定大小时重新启动子进程 那就太好了 我怎样才能做到这一点 您应该能够从 proc PID
  • PyQt5 - 无法使用 QVideoWidget 播放视频

    from PyQt5 QtWidgets import from PyQt5 QtMultimedia import from PyQt5 QtMultimediaWidgets import from PyQt5 QtCore impor
  • Capistrano 3 部署无法连接到 GitHub - 权限被拒绝(公钥)

    我使用 Capistrano v3 和 capistrano symfony gem 设置了以下部署脚本 我正在使用 Ubuntu 14 4 部署到 AWS EC2 实例 我正在连接从 AWS 下载的 pem 文件 我的deploy rb中
  • 在 unix 中编译 dhrystone 时出错

    我是使用基准测试和 makefile 的新手 我已经从下面的链接下载了 Dhrystone 基准测试 我正在尝试编译它 但我遇到了奇怪的错误 我尝试解决它 但没有成功 有人可以帮助我运行 dhrystone 基准测试吗 以下是我尝试编译的两
  • Mcrt1.o和Scrt1.o有什么用?

    我坚持使用以下两个文件 即 Mcrt1 o 和 Scrt1 o 谁能帮我知道这两个文件的用途 如何使用它 我们以 gcrt1 o 为例 在使用 pg 选项编译进行性能测试时非常有用 谢谢 表格的文件 crt o总是 C 运行时启动代码 大部
  • vagrant ssh -c 并在连接关闭后保持后台进程运行

    我正在编写一个脚本来启动和后台流浪机器内的进程 似乎每次脚本结束和 ssh 会话结束时 后台进程也会结束 这是我正在运行的命令 vagrant ssh c cd vagrant src nohup python hello py gt he
  • 让 TeXstudio 在 linux mint 中工作:找不到文件“url.sty”。

    刚刚切换到 Linux Mint 以前的顽固 Windows 用户 我在尝试安装 TeXstudio 时遇到一些问题 Sudo apt get install texstudio 给了我一个正确的安装 至少 我是这么认为的 但是当我尝试构建
  • 如何从 C 程序中获取 NIC 详细信息?

    我想要获取连接到我的计算机的所有 NIC 的以下详细信息 1 接口名称 例如eth0 2 接口编号 如Windows http answers yahoo com question index qid 20080517041705AAOmJ
  • linux命令中括号的用途是什么[重复]

    这个问题在这里已经有答案了 我在 Linux 终端中运行以下命令 谁能告诉我 Linux 终端中括号和以下命令的用途是什么 echo GET HTTP 1 0 echo 主机 www google com echo 数控 www googl
  • Linux中使用管道进行进程间通信

    我已经编写了在 linux 中写入数字以进行管道传输的代码 如下所示 但显示错误 任何人都可以帮助我解决这个问题 基本上该程序的问题陈述如下 一个程序将打开一个管道 向管道写入一个数字 其他程序将打开同一管道 读取数字并打印它们 关闭两个管
  • 如何将后台作业的输出分配给 bash 变量?

    我想在 bash 中运行后台作业并将其结果分配给一个变量 我不喜欢使用临时文件 并且希望同时运行多个类似的后台任务 root root var echo hello world root root echo var hello world
  • linux下写入后崩溃

    如果我使用 write 将一些数据写入磁盘上的文件会发生什么 但我的应用程序在刷新之前崩溃了 如果没有系统故障 是否可以保证我的数据最终会刷新到磁盘 如果您正在使用write 并不是fwrite or std ostream write 那
  • 推荐用于小型站点的 IRC 服务器 (ircd)? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 情况 我想使用 IRC 机器人作为我正在研究的其他代码的通用通信接口 服务器硬件陈旧且内存不足 但运行在相对最新的 Debian GNU
  • 这种 bash 文件名提取技术有何用途?

    我有一部分 bash 脚本正在获取不带扩展名的文件名 但我试图了解这里到底发生了什么 是做什么用的 有人可以详细说明 bash 在幕后做了什么吗 如何在一般基础上使用该技术 bin bash for src in tif do txt sr
  • Fortran 中的共享库,最小示例不起作用

    我试图了解如何在 Linux 下的 Fortran 中动态创建和链接共享库 我有两个文件 第一个 liblol f90 看起来像这样 subroutine func print lol end subroutine func 我用它编译gf
  • 未找到 Gem 命令

    我已经在 Ubuntu 10 10 32 位上安装了 gem apt get install gem y 但当我尝试跑步时 gem install something gem 我收到未找到命令的错误 bash gem command not
  • C++:Linux平台上的线程同步场景

    我正在为 Linux 平台实现多线程 C 程序 其中我需要类似于 WaitForMultipleObjects 的功能 在搜索解决方案时 我发现有一些文章描述了如何在 Linux 中实现 WaitForMultipleObjects 功能
  • 运行此处编译的 C 程序会导致在另一台服务器上找不到 GLIBC 库错误 - 是我的错还是他们的错?

    此处编译的 C 程序在我们的 Ubuntu 服务器上运行良好 但是当其他人尝试在他们的特定 Linux 服务器上运行它时 他们会收到以下错误 myprog install lib tls libc so 6 version GLIBC 2
  • XAMPP Windows 上的 Php Cron 作业

    嗯 我是这个词的新手CRON 据我所知 这是一个Unix安排特定操作在定义的时间间隔后执行的概念 我需要运行一个php文件 每小时更新一次数据库 但我的困惑在于安排执行 我在用XAMPP用于 Windows 7 上的本地开发测试 我发现了什

随机推荐

  • 如何在 Debian 11/10 上安装和使用 Cordova

    阿帕奇科尔多瓦是一个开源移动开发框架 它允许您使用 HTML5 CSS3 和 JavaScript 等标准 Web 技术进行跨平台开发 避免使用每个移动平台的本机开发语言 Apache Cordova 命令行需要 Node js 才能运行
  • 如何在 Ubuntu 16.04 LTS 上安装 Swift

    Swift 是一种安全 快速 富有表现力的通用编程语言 专为软件设计模式而构建 它最适合系统编程 移动和桌面应用程序 Swift 提供了大量功能 使编程变得更加容易 同时为开发人员提供了真正的系统编程语言所需的控制能力 本教程将帮助您在 U
  • 如何在 Fedora Linux 上安装 Git

    Git 是一个分布式版本控制系统 广泛应用于软件开发和其他协作项目 在本指南中 我们将介绍在 Fedora Linux 上安装 Git 的两种方法 使用官方存储库和从最新源代码编译 先决条件 确保您有一个运行 Fedora Linux 的系
  • 如何在 Python 中计算两个日期之间的天数

    在 Python 中处理日期和时间时 计算两个日期之间的天数是一项常见任务 无论您是构建预订系统 日程安排工具还是任何其他涉及日期和时间的应用程序 计算两个日期之间的天数都是一个关键功能 在本文中 我们将讨论如何在 Python 中计算两个
  • 什么是中间人 (MITM) 攻击?

    A 中间人 MITM 攻击是一种常见的网络安全威胁 如果处理不当 可能会造成严重后果 在这种类型的攻击中 恶意行为者会拦截 中继并可能改变认为彼此直接通信的两方之间的通信 本文将深入探讨 MITM 攻击带来的威胁 攻击者使用的技术以及个人和
  • 如何利用技术进步实现完美的远程办公

    远程工作并不是一个新趋势 作家 记者和艺术家总是有机会在舒适的家中工作 尽管如此 远程办公始终与技术密切相关 在过去 远程工作人员依赖邮件服务和交通 随着这两个领域变得越来越好 越来越多的人能够在家执行工作任务 然而 直到互联网的出现 这种
  • 如何在 Debian 9 上设置 Apache 虚拟主机

    在本教程中 我们将引导您了解如何在 Debian 9 上设置 Apache 虚拟主机 Apache 虚拟主机允许您在一台计算机上托管多个域 使用虚拟主机时 您可以为每个域或子域指定不同的文档根 包含网站文件的目录 创建单独的安全策略 使用不
  • 如何在 CentOS 8 上安装 R

    R 是一种开源编程语言和免费环境 专门从事统计计算和图形表示 它由 R 统计计算基金会支持 主要供统计学家和数据挖掘人员用于开发统计软件和执行数据分析 本文介绍如何在 CentOS 8 上安装 R 先决条件 在继续本教程之前 请确保您已满足
  • 如何更改 SFTP 端口

    SFTP SSH 文件传输协议 是一种安全文件协议 用于通过加密连接在两台主机之间传输文件 它还允许您对远程文件执行各种文件操作并恢复文件传输 SFTP 可用作旧版 FTP 协议的替代品 它具有 FTP 的所有功能 但连接更安全 本文介绍如
  • 如何在 Ubuntu 18.04 上设置或更改时区

    在 Ubuntu 上 系统的时区是在安装过程中设置的 但以后可以轻松更改 使用正确的时区对于许多与系统相关的任务和流程都很重要 例如 cron 守护进程使用系统的时区来执行 cron 作业 并且日志文件中的时间戳基于相同的时区 本教程演示如
  • 如何在 Debian 9 上安装 Yarn

    Yarn 是一个与 npm 兼容的 JavaScript 包管理器 它的创建是为了解决 npm 的一系列问题 例如通过并行操作加快软件包安装过程并减少与网络连接相关的错误 在本教程中 我们将指导您如何安装Yarn在 Debian 9 系统上
  • 如何在 Ubuntu 18.04 上安装 Django

    Django 是一个免费开源的高级 Python Web 框架 旨在帮助开发人员构建安全 可扩展和可维护的 Web 应用程序 有不同的方法来安装 Django 具体取决于您的需要 它可以在系统范围内安装 也可以使用 pip 安装在 Pyth
  • 如何在 Linux 中添加目录到 PATH

    当您在命令行上键入命令时 您基本上是在告诉 shell 运行具有给定名称的可执行文件 在Linux中 这些可执行程序就像ls find file和其他文件 通常位于系统上的几个不同目录中 存储在这些目录中的任何具有可执行权限的文件都可以从任
  • 如何在 CentOS 8 上设置或更改时区

    使用正确的时区对于许多与系统相关的任务和流程至关重要 例如 cron 守护进程使用系统的时区来执行 cron 作业 并且日志文件中的时间戳基于同一系统的时区 在 CentOS 上 系统的时区是在安装过程中设置的 但以后可以轻松更改 本文介绍
  • Python range() 函数

    蟒蛇rangetype 通过定义范围的起点和终点来生成整数序列 它通常与for循环迭代数字序列 range 在 Python 2 和 3 中的工作方式有所不同 在Python 2中 有两个函数可以让你生成整数序列 range and xra
  • Linux 中的正常运行时间命令

    在本教程中 我们将介绍uptime命令 顾名思义 uptime命令显示系统已经运行了多长时间 它还显示当前时间 登录用户数以及过去 1 5 和 15 分钟的系统负载平均值 如何使用正常运行时间命令 uptime 命令的语法如下 uptime
  • 如何在 CentOS 7 上使用 VSFTPD 设置 FTP 服务器

    FTP 文件传输协议 是一种标准的客户端 服务器网络协议 允许用户在远程网络之间传输文件 有多种可用于 Linux 的开源 FTP 服务器 最流行和最广泛使用的是PureFTPd ProFTPD and vsftpd 在本教程中 我们将在
  • Python while 循环

    循环是编程语言的基本概念之一 当您想要多次重复特定的代码块直到满足给定条件时 循环会很方便 Python中有两种基本的循环结构 for and while loops 本教程涵盖了以下基础知识whilePython 中的循环 我们还将向您展
  • NumPy loadtxt 教程(从文件加载数据)

    在之前的教程中 我们讨论过NumPy 数组 我们看到了它如何使读取 解析和对数字数据执行操作的过程变得轻而易举 在本教程中 我们将讨论 NumPy loadtxt 方法 该方法用于解析文本文件中的数据并将其存储在 n 维 NumPy 数组中
  • Linux Bash 脚本编写第 3 部分 – 参数和选项

    到目前为止 您已经了解了如何编写无需用户输入即可完成工作的 Linux bash 脚本 今天我们将继续我们的 Linux bash 脚本系列 如果您想了解我们在谈论什么 我建议您查看之前的帖子 Bash 脚本基础知识 Bash 脚本 For