missing-semester 第二节

本文详细介绍了Shell脚本的基础概念,包括变量赋值规则、双引号和单引号的区别、流程控制语句(if,while,for)、xargs函数的应用以及find和ls命令的结合实例。
摘要由CSDN通过智能技术生成

shell 脚本

shell也是一种编程语言

定义变量 foo=bar 中间不能有空格,如foo = bar 否则会被机器认为foo是一个函数带了两个参数=和bar之后$foo可以读出foo变量里的值bar

[root@master ~]# foo=bar
[root@master ~]# echo "$foo"
bar
[root@master ~]# echo '$foo'
$foo

这里双引号 " " 会让里面可以转义的字符转义(或者说eval了一下里面的内容),但是单引号  ' ' 不会。

mcd () {
    mkdir -p "$1"
    cd "$1"
}

课件中mkdir里 -p的参数表示确保后面的文件存在,如果不存在就创建一个

后面的$1表示第一个参数,常见的有特殊含义的保留字如下

  • $0 - 脚本名
  • $1$9 - 脚本的参数。 $1 是第一个参数,依此类推。
  • $@ - 所有参数
  • $# - 参数个数
  • $? - 前一个命令的返回值
  • $$ - 当前脚本的进程识别码
  • !! - 完整的上一条命令,包括参数。常见应用:当你因为权限不足执行命令失败时,可以使用 sudo !!再尝试一次。
  • $_ - 上一条命令的最后一个参数。如果你正在使用的是交互式 shell,你可以通过按下 Esc 之后键入 . 来获取这个值。

 bash里的||和&&和c语言中一样都是短路运算符

false || echo "Oops, fail"
# Oops, fail

true || echo "Will not be printed"
#

true && echo "Things went well"
# Things went well

false && echo "Will not be printed"
#

false ; echo "This will always run"
# This will always run

 命令替换 $(命令)

$(command)会被替换为命令的执行结果

如下图的$(ls)替换为了两个文件名显示了两个文件的内容$(date)被替换为了当前时间

[root@master try]# ls
example.sh  mcd.sh
[root@master try]# cat $(ls)
#!/bin/bash

echo "Starting program at $(date)"

echo "Running program $0 with $# agruments with pid $$"

for file in "$@"; do
	grep foobar "$file" > /dev/null 2> /dev/null
	# When pattern is not found,grep has exit status
	# We redirect STDOUT and STDERR to a null register

	if [[ "$?" -ne 0 ]]; then
	  echo "file $file does not have any foobar adding one"
	  echo "# foobar" >> "$file"
	fi
done

mcd ()
{
   mkdir -p "$1"
   cd "$1"
}
# foobar

 进程替换process substitution), <( CMD ) 会执行 CMD 并将结果输出到一个临时文件中,并将 <( CMD ) 替换成临时文件名。这在我们希望返回值通过文件而不是STDIN传递时很有用。例如, diff <(ls foo) <(ls bar) 会显示文件夹 foobar 中文件的区别。

这是另外一种替换方式会用了可以通过文件进行输入输出

[root@master ~]# touch foo{1,2,3,4}
[root@master ~]# ls
anaconda-ks.cfg  foo3    mysql80-community-release-el7-5.noarch.rpm  project2
foo1             foo4    mysql-connector-java-5.1.45                 project42
foo2             mcd.sh  project1                                    try
[root@master ~]# touch foo{1,2,3,4}/test{1,2,3,4}

foo{1,2,3,4}会被扩展为foo1 foo2 foo3 foo4

bash的输入输出重定向

  • >:将标准输出重定向到指定文件,会覆盖文件原有内容。
  • >>:将标准输出重定向到指定文件,会追加到文件末尾而不会覆盖原有内容。
  • 2>:将标准错误重定向到指定文件,会覆盖文件原有内容。
  • 2>>:将标准错误重定向到指定文件,会追加到文件末尾而不会覆盖原有内容。
  • &>:将标准输出和标准错误同时重定向到指定文件,会覆盖文件原有内容。
  • &>>:将标准输出和标准错误同时重定向到指定文件,会追加到文件末尾而不会覆盖原有内容。

 bash的while,for,if语法

在 Bash 中,ifwhilefor 是常用的流程控制语句,它们的基本语法如下:

  1. if
    if condition
    then
        # code block executed if the condition is true
    else
        # code block executed if the condition is false
    fi
    

    在 Bash 脚本中,if 语句后面加分号 ; 是可选的,并不是必需的。在大多数情况下,可以省略这个分号,而代码仍然能够正确执行。

    分号 ; 在 Bash 中用于分隔多个命令或语句。在 if 语句的情况下,如果在 then 关键字后面直接换行,Bash 会自动理解 then 是单独的一条命令,不需要使用分号。

if 语句用于根据条件执行不同的代码块。condition 是一个测试表达式,如果它的返回值为 0(真),则执行 then 后的代码块,否则执行 else 后的代码块(如果有)。fi表示代码块的终止

  1. while 循环:
while condition
do
    # code block executed while the condition is true
done

循环会不断执行代码块,直到 condition 的返回值为 0(假)。每次循环开始时,都会检查 condition,如果为真,则执行循环内的代码块。当 condition 为假时,循环结束。

  1. for 循环:
for variable in list
do
    # code block executed for each item in the list
done
 
 for循环用于遍历列表中的每个元素,并执行相应的代码块。 
 variable 是一个用于存储列表中当前元素的变量,而 
 list 是要遍历的元素列表。(支持类似c语言的for结构) 
 

这些语法规则是 Bash 中基本的流程控制结构,通过它们可以实现条件判断和循环操作。在实际使用中,可以根据具体需求组合和嵌套这些语句,以构建复杂的逻辑和循环结构。

习题解答

Solution-Shell 工具和脚本 · the missing semester of your cs education

xargs 函数

捕获一个命令的输出传递给另外一个命令,和管道一起使用-d的参数表示分隔符的选择,如习题里分隔符应该选择'\n'换行符而不是空格。

这段命令是一个用于查找当前目录下的所有文件,并按照修改时间进行排序后,输出最近修改的文件的信息的命令。

find . -type f -print0 | xargs -0 ls -lt | head -1命令的解释

让我们逐步解释这个命令:

  1. find . -type f -print0: 这部分使用 find 命令来查找当前目录(.)下的所有文件(不包括目录)。-type f 表示只查找文件,而不包括目录。-print0 表示以 null 字符(\0)作为文件名的分隔符输出结果,这样可以正确处理文件名中包含空格或特殊字符的情况。

  2. |: 这是管道符号,它将 find 命令的输出传递给下一个命令。

  3. xargs -0 ls -lt: 这部分使用 xargs 命令将 find 的输出作为参数传递给 ls 命令。-0 表示以 null 字符作为参数的分隔符,与 find 命令中的 -print0 对应。ls -lt 表示以长格式(详细信息)列出文件,并按照修改时间从最新到最旧进行排序。-l表示详细信息-t表示按时间排序

  4. head -1: 最后,使用 head 命令仅显示排序后的结果的前一行,也就是显示最近修改的文件信息。

  5. -mmin 60表示最近60分钟内修改的信息

 可能会提示因信号13而终止,因为使用了head 函数在head已经捕获了需要的输入之后xargs仍然在输入引起的管道破裂

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值