Linux_shell管道命令及调试-06

一:管道命令

Linux命令大全

Linux 命令大全 | 菜鸟教程

1.1:seq

seq 命令在 Linux 系统中是一个非常实用的命令行工具,它用于生成一个数字序列。这个命令通常用于循环、测试或任何需要一系列数字作为输入的场景。seq 可以生成从指定起始值到结束值的连续整数序列,还可以指定步长(增量)。

基本语法

seq [选项]... 尾数  
seq [选项]... 起始数 尾数  
seq [选项]... 起始数 增量 尾数

常用选项

  • -f 或 --format:指定输出格式,允许使用 printf 风格的格式字符串。
  • -s 或 --separator:定义输出序列中数字之间的分隔符,默认是换行符 \n
  • -w 或 --equal-width:确保输出的每个数字宽度相同,通过在前面填充零来实现。

示例:

1. 生成从 1 到 5 的数字序列

seq 5

输出:

1  
2  
3  
4  
5

2. 生成从 10 到 20 的数字序列

seq 10 20

输出:

10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20

3. 以2为步长,从1到9的数字序列

seq 1 2 9

输出

1  
3  
5  
7  
9

4. 使用-s选项自定义分隔符

seq -s ',' 1 5

输出:

1,2,3,4,5

5. 使用-f选项格式化输出

seq -f "%02g" 1 5

输出:

01  
02  
03  
04  
05

这里 %02g 表示输出两位宽的数字,不足部分用 0 填充。

1.2:管道命令

管道命令的概念

管道是由两个或多个命令组成的,前一个命令的输出作为后一个命令的输入

Linux管道命令是 “ | ”,其作用是用来连接多条指令,前一条指令的输出流会作为后一条指令的操作对象,其命令格式为“指令1 | 指令2 | …”,该命令的后一条指令,必须能够接收标准输入流命令才能执行。

它只能处理由前面一条指令传出的正确输出信息,对错误信息是没有直接处理能力的。然后,传递给下一条指令,作为操作对象。

管道命令的常用场景

  1. 过滤数据:通过管道将某个命令的输出传递给grep等过滤命令,以筛选出包含特定文本的行。
  2. 排序数据:使用sort命令对管道传递的数据进行排序。
  3. 统计数据:结合wc等命令,对管道传递的数据进行行数、字符数等统计。
  4. 文本处理:利用awk、sed等文本处理工具,对管道传递的文本进行复杂的编辑和格式化。

基本格式

指令1 | 指令2 | …

注意:

1、管道命令只能处理前一条指令的正确输出,不能处理错误输出;

2、管道命令的后一条指令,必须能够接收标准输入流命令才能执行。

3,标准输出与标准错误:默认情况下,管道命令只传递标准输出(stdout),不传递标准错误(stderr)。如果需要同时传递标准错误,可以使用重定向操作符2>&1

4,命令兼容性:不是所有命令都支持管道输入,有些命令可能只能接受文件作为输入。在这种情况下,可以使用xargs等命令将管道输入转换为文件参数。

seq 20 100 | head -n 50 | tail -n 1

1.3 分类

管道可以分为以下几种类型:

一、标准管道(Standard Pipe)

  • 定义:标准管道是最常用的管道类型,它通过文件描述符(stdin、stdout、stderr)进行通信。
  • 表示方法:通常使用竖线(|)作为管道操作符。
  • 作用:将前一个命令的输出作为后一个命令的输入。
  • 示例ls | grep txt,表示将ls命令的输出作为grep命令的输入,筛选出包含"txt"的文件名。

二、命名管道(Named Pipe)

  • 定义:命名管道也称为FIFO(First In First Out),它允许通过文件名进行通信,而不仅仅是文件描述符。
  • 特点:命名管道在文件系统中有一个对应的文件名,可以像普通文件一样进行打开、读写等操作,但它实际上是一种特殊的文件类型,用于进程间通信。
  • 使用场景:适用于需要持久化通信场景或在不同会话间进行通信的情况。

三、匿名管道(Anonymous Pipe)

  • 定义:匿名管道也称为PTY(Process Terminal),它是用于进程间通信的一种特殊管道类型。
  • 特点:与命名管道不同,匿名管道没有对应的文件名,它只能在创建它的进程及其子进程或子进程的子进程之间使用。
  • 使用场景:主要用于shell命令之间的连接和数据传递,如前面提到的标准管道就是匿名管道的一种表现形式。

1.4常用管道命令

1. grep

  • 功能:文本搜索工具,用于在文本或标准输入中查找指定的匹配,并输出到标准输出上。
  • 常用选项
    • -i:忽略大小写。
    • -n:输出时加上行号。
    • -v:反向选择,只显示不包含匹配的行。
    • -E:将查找模式解释成扩展的正则表达式。
    • -F:将查找模式解释成单纯的字符串。
  • 示例grep 'Hello' hi.txt 在文件hi.txt中查找包含"Hello"的行。

2. cut

  • 功能:截取字符串,显示到标准输出上。
  • 常用选项
    • -d:表示分隔符,默认为TAB。
    • -f:以字段为单位,截取指定字段。
    • -c:以字符为单位,截取指定字符范围。
  • 示例echo $PATH | cut -d ':' -f 3,5 截取环境变量PATH中的第3和第5个字段。

3. sort

  • 功能:将文件内容排序,显示到标准输出上。
  • 常用选项
    • -n:依照数值的大小排序。
    • -r:按逆序排序。
    • -t:指定字段分隔符,默认为TAB。
    • -k:指定从哪个字段开始排序。
  • 示例cat /etc/passwd | sort -t ':' -k 3 -n 按UID对/etc/passwd文件进行排序。

4. uniq

  • 功能:将排序好后文件中的重复行去除。
  • 常用选项
    • -c:在每行的行首加上该行在文件中出现的次数。
    • -i:忽略大小写。
  • 示例cat /etc/passwd | cut -d ':' -f4 | sort -n | uniq -c 统计/etc/passwd文件中每个GID的出现次数。

5. wc

  • 功能:计数命令,用于统计字数、行数等。
  • 常用选项
    • -l:统计行数。
    • -w:统计字数。
    • -m:统计字符数。
  • 示例wc -l filename 统计文件filename的行数。

6. tee

  • 功能:双重重定向,将数据传送到文件和屏幕。
  • 常用选项
    • -a:以累加的方式添加到文件。
  • 示例echo "Hello, World!" | tee file.txt 将"Hello, World!"输出到屏幕和file.txt文件中。

7. tr

  • 功能:输出一段信息中的文字,或者进行文字信息的替换。
  • 常用选项
    • -d:删除信息中的指定字符串。
    • -s:替换掉重复的字符。
  • 示例echo "hello world" | tr 'a-z' 'A-Z' 将小写字母替换成大写字母。

8. join

  • 功能:处理两个文件之间的内容,将两个文件中有相同数据的哪一行加在一起。
  • 常用选项
    • -t:指定输入输出的分隔符。
    • -i:忽略大小写。
    • -1-2:指定第一个和第二个文件要比较的字段。
  • 示例join -t ':' /etc/passwd /etc/shadow 将/etc/passwd和/etc/shadow文件按第一个字段进行整合。

9. paste

  • 功能:将文件的同一行粘贴在一起,中间以tab分开。
  • 常用选项
    • -d:指定分隔符。
  • 示例paste file1 file2 将file1和file2的同一行内容粘贴在一起,中间以tab分隔。

10. paste

  • 功能:将输入文本中的每个制表符(\t)转换为指定数量的空格,默认情况下是8个空格。
  • 常用选项
    • -t N:指定每个制表符应替换为N个空格。默认值是8。
    • --version:显示命令版本信息。
    • --help:显示帮助文档。
    • -i 或 --initial:仅当制表符导致输出行超过输入行的长度时才进行替换。这有助于保持原始文件的列对齐。
    • -f:保留每个制表符之前的空格。默认情况下,expand会删除制表符之前的所有空格。
  • 示例
  • 假设我们有一个名为input.txt的文件,内容如下:
  • Hello	world from expand!  
    This	is a test.

    如果我们想将每个制表符替换为4个空格,可以执行以下命令:

  • expand -t 4 input.txt

    输出将是:

  • Hello    world from expand!  
    This    is a test.

11. 切割命令split

  • 功能:将大文件分割成较小的文件,在默认情况下将按照每1000行切割成一个小文件
  • 常用选项
    • -b 或 --bytes=SIZE:以指定的字节数分割文件。SIZE可以是一个整数,后面可以跟k(表示KB)、M(表示MB)或G(表示GB)等单位。
    • -l 或 --lines=NUMBER:以指定的行数分割文件。NUMBER是每个分割文件中应包含的行数。
    • -C 或 --line-bytes=SIZE:尝试按指定大小的行分割文件,但会尽量维持每行的完整性。
    • -a 或 --suffix-length=N:指定输出文件名后缀的长度,默认为2。
    • -d 或 --numeric-suffixes:使用数字后缀代替默认的字母后缀。
    • --verbose:打印详细的信息到标准输出,显示分割进度。
    • --help:显示帮助信息。
    • --version:显示版本信息。
  • 示例split [-parameter] 切割文件 filename

二:数据流定向

  • 标准输入in:代码0,使用 < 或者 <<

  • 标准输出out:代码1,使用 > 或者 >>

  • 错误输出:代码2,使用 > 或者 >>

    • > 表示 写入; >>表示追加

    • <表示 读入;<<表示结束读入

2>&1:2>&1表示将标准错误输出(stderr)重定向到标准输出(stdout)。command 2>&1,表示将command命令的标准错误输出和标准输出合并,并一起显示。

示例

读取data.txt的内容,追加到data2.txt中

cat data.txt >> data2.txt

 

cat >> 2.txt << EOF

示例:

创建目录脚本(1.sh):

#!/bin/bash

# 标准输出
echo '标准输出内容'
# 错误输出
cho '错误'

标准输出(stdout)输出到到日志文件中

./1.sh >1.log

./1.sh 1>1.log

标准错误输出(stderr)输出到日志文件中

./1.sh 2>1.log

标准输出(stdout)和标准错误输出(stderr)同时输出到到日志文件中

./1.sh >1.log 2>&1

2>&1:表示将标准错误输出(stderr)重定向到标准输出(stdout),这样,即使删除目录失败,也不会影响创建目录的结果,错误信息也会被记录到output.txt文件中。

三:脚本调试

Shell编程中,调试是一个重要的环节,它帮助我们查找脚本中的问题并进行修复。同时,合理的错误处理也是编写健壮的Shell脚本的关键 。

3.1 调试工具和技巧

3.1.1 echo命令

在Shell脚本中,我们可以使用echo命令输出一些中间结果,以便在运行脚本时查看变量的取值和程序流程。例如:

#!/bin/bash

name="John"
echo "The name is: $name"

3.1.2 set -x

使用set -x命令可以在脚本执行过程中显示每个命令及其参数,非常有助于查看脚本的执行流程。

#!/bin/bash

set -x

name="John"
age=30

echo "Name: $name"
echo "Age: $age"

3.1.3 set -e

使用set -e命令可以在脚本执行过程中,一旦出现非零返回值的命令,立即退出脚本。这对于快速发现错误非常有帮助。

# 程序出错,立刻中断执行
# set -e

add(){
	# 函数出错,继续向下执行,函数的调用结果看最后一行命令的执行结果
	cho 'add方法'
	echo '结束'
}

add
# echo '结束'是函数的执行结果
echo 'add方法的调用结果:'$?

3.1.4 调试器:bash -x

如果脚本比较复杂,使用上述方法可能不够方便。我们可以通过在终端中运行脚本,并加上-x选项来调试整个脚本

bash -x 1.sh

3.2 错误处理

在Shell脚本中,错误处理是确保脚本在运行过程中能够适当地处理各种异常情况的关键。

3.2.1. 检查命令返回值

在脚本中执行命令后,可以通过$?变量来获取命令的返回值。通常,返回值为0表示命令成功执行,非零值表示命令执行失败。

#!/bin/bash

ls /path/to/non_existent_dir

if [ $? -ne 0 ]; then
  echo "Error: Directory not found."
fi

3.2.2 使用exit命令退出脚本

在脚本中,如果发现错误或者异常情况,可以使用exit命令终止脚本的执行,并返回一个非零值表示错误。

#!/bin/bash

file="/path/to/non_existent_file"

if [ ! -f "$file" ]; then
  echo "Error: File not found."
  exit 1
fi

3.2.3 使用trap命令捕获信号

使用trap命令可以捕获脚本接收到的信号,并执行相应的操作。这样可以在脚本执行过程中优雅地处理中断。

以下是 trap 命令的十种主要用法及其代码示例:

*用法**示例代码*
捕获并处理指定信号trap 'echo "Signal received."' INT
忽略指定信号trap '' TERM
恢复默认的信号处理方式trap - INT
设置 EXIT 信号处理函数trap 'cleanup' EXIT
在函数内部设置 RETURN 信号处理函数func() { trap 'cleanup' RETURN; ... }
清除所有已设置的信号处理函数trap - INT TERM EXIT
执行命令并在结束时恢复先前的信号处理方式trap 'cmd' EXIT; cmd
在循环中使用 trap 避免在接收到信号时终止循环while true; do trap 'break' INT; ... ; done
使用函数作为信号处理函数trap 'cleanup' INT; cleanup() { echo "Cleaning up..."; }
处理多个信号trap 'echo "Signal 1 received."' SIGUSR1; trap 'echo "Signal 2 received."' SIGUSR2

1 清理资源
#!/bin/bash

cleanup() {
    echo "Cleaning up..."
    # 执行清理操作,例如关闭文件描述符、删除临时文件等
}

# 设置 EXIT 信号处理函数
trap cleanup EXIT

# 其他代码逻辑
2 记录错误日志
#!/bin/bash

log_file="error.log"

# 定义错误处理函数,将错误信息记录到日志文件
handle_error() {
    echo "$(date): $BASH_COMMAND failed with exit code $?" >> "$log_file"
    exit 1
}

# 设置 ERR 信号处理函数
trap handle_error ERR

# 其他代码逻辑
cat no_such_file.txt
3 忽略特定信号
#!/bin/bash  
 
trap 'echo "Caught SIGINT"; exit' INT
 
echo "Script is running. Try pressing Ctrl+C."  
while true; do  
    sleep 1  
done
4 优雅处理脚本终止
#!/bin/bash

cleanup() {
    echo "Performing cleanup..."
    # 清理操作
}

# 设置 EXIT 信号处理函数
trap cleanup EXIT

# 主要代码逻辑
echo "Running script..."

# 模拟脚本执行过程中的异常终止
if [[ "$1" == "error" ]]; then
    echo "Error occurred."
    exit 1
fi

echo "Script completed successfully."

CentOS 7(以及大多数类Unix/Linux系统)中,信号是进程间通信的一种方式,用于通知进程某个事件的发生。这些信号具有预定义的编号和名称,并且大多数系统信号在POSIX标准中都有定义。以下是一些CentOS 7中常用的信号列表,这些信号可以通过kill命令或其他方式发送给进程: 信号编号信号名称描述 SIGHUP 终端挂起或用户退出。常用于通知进程重新读取配置文件并重启。 SIGINT 中断信号,通常由Ctrl+C产生,要求进程立即停止。 SIGQUIT 退出信号,生成core dump后退出。 SIGABRT 由abort()函数产生,导致程序异常终止。 SIGKILL 强制杀死进程,该信号不能被捕获、阻塞或忽略。 SIGALRM 定时器超时。 SIGTERM 请求程序终止。这是kill命令的默认信号,可以被捕获、阻塞或忽略。 SIGCONT 如果进程已停止(例如,收到SIGSTOP信号),则继续执行。 SIGSTOP 停止进程的执行,不能被捕获、阻塞或忽略。 SIGTSTP 终端停止信号,通常由Ctrl+Z产生。 注意: 这个列表并不包含所有可用的信号,只是列出了一些常用的信号。 信号编号和名称在大多数Unix和类Unix系统中都是相同的,因为它们遵循POSIX标准。 你可以使用kill -l命令在CentOS 7中查看所有可用的信号及其编号和名称。 此外,还有一些实时信号(实时信号编号通常从34开始),但这些信号在日常使用中相对较少见,主要用于需要高精度控制的场景。对于大多数用户和应用程序来说,上述列出的信号已经足够使用。

  • 15
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值