linux shell 高级,Linux Shell高级技巧

一、在循环中使用管道的技巧:

在Bash Shell中,管道的最后一个命令都是在子Shell中执行的。这意味着在子Shell中赋值的变量对父Shell是无效的。所以当我们将管道输出传送到一个循环结构,填入随后将要使用的变量,那么就会产生很多问题。一旦循环完成,其所依赖的变量就不存在了。

/> cat > test8_1.sh

#!/bin/sh

#1. 先将ls -l命令的结果通过管道传给grep命令作为管道输入。

#2. grep命令过滤掉包含total的行,之后再通过管道将数据传给while循环。

#3. while read line命令从grep的输出中读取数据。注意,while是管道的最后一个命令,将在子Shell中运行。

ls -l | grep -v total | while read line

do

#4. all变量是在while块内声明并赋值的。

all="$all $line"

echo $line

done

#5. 由于上面的all变量在while内声明并初始化,而while内的命令都是在子Shell中运行,包括all变量的赋值,因此该变量的值将不会传递到while块外,因为块外地命令是它的父Shell中执行。

echo "all = " $all

/> ./test8_1.sh

-rw-r--r--.  1 root root 193 Nov 24 11:25 outfile

-rwxr-xr-x. 1 root root 284 Nov 24 10:01 test7.sh

-rwxr-xr-x. 1 root root 108 Nov 24 12:48 test8_1.sh

all =

为了解决该问题,我们可以将while之前的命令结果先输出到一个临时文件,之后再将该临时文件作为while的重定向输入,这样while内部和外部的命令都将在同一个Shell内完成。

/> cat > test8_2.sh

#!/bin/sh

#1. 这里我们已经将命令的结果重定向到一个临时文件中。

ls -l | grep -v total > outfile

while read line

do

#2. all变量是在while块内声明并赋值的。

all="$all $line"

echo $line

#3. 通过重定向输入的方式,将临时文件中的内容传递给while循环。

done 

#4. 删除该临时文件。

rm -f outfile

#5. 在while块内声明和赋值的all变量,其值在循环外部仍然有效。

echo "all = " $all

/> ./test8_2.sh

-rw-r--r--.  1 root root   0 Nov 24 12:58 outfile

-rwxr-xr-x. 1 root root 284 Nov 24 10:01 test7.sh

-rwxr-xr-x. 1 root root 140 Nov 24 12:58 test8_2.sh

all =  -rwxr-xr-x. 1 root root 284 Nov 24 10:01 test7.sh -rwxr-xr-x. 1 root root 135 Nov 24 13:16 test8_2.sh

上面的方法只是解决了该问题,然而却带来了一些新问题,比如临时文件的产生容易导致性能问题,以及在脚本异常退出时未能及时删除当前使用的临时文件,从而导致生成过多的垃圾文件等。下面将再介绍一种方法,该方法将同时解决以上两种方法同时存在的问题。该方法是通过HERE-Document的方式来替代之前的临时文件方法。

/> cat > test8_3.sh

#!/bin/sh

#1. 将命令的结果传给一个变量

OUTFILE=`ls -l | grep -v total`

while read line

do

all="$all $line"

echo $line

done <

#2. 将该变量作为该循环的HERE文档输入。

$OUTFILE

EOF

#3. 在循环外部输出循环内声明并初始化的变量all的值。

echo "all = " $all

/> ./test8_3.sh

-rwxr-xr-x. 1 root root 284 Nov 24 10:01 test7.sh

-rwxr-xr-x. 1 root root 135 Nov 24 13:16 test8_3.sh

all =  -rwxr-xr-x. 1 root root 284 Nov 24 10:01 test7.sh -rwxr-xr-x. 1 root root 135 Nov 24 13:16 test8_3.sh

二、自链接脚本:

通常而言,我们是通过脚本的命令行选项来确定脚本的不同行为,告诉它该如何操作。这里我们将介绍另外一种方式来完成类似的功能,即通过脚本的软连接名来帮助脚本决定其行为。

文件名:test9.sh

#!/bin/sh

#basename命令将剥离脚本的目录信息,只保留脚本名,从而确保在相对路径的模式下执行也没有任何差异。

#通过sed命令过滤掉脚本的扩展名。

dowhat=`basename $0 | sed 's/\.sh//'`

echo $dowhat

#这里的case语句只是为了演示方便,因此模拟了应用场景,在实际应用中,可以为不同的分支执行不同的操作,或将某些变量初始化为不同的值和状态。

case $dowhat in

test9)

echo "I am test9.sh"

;;

test9_1)

echo "I am test9_1.sh."

;;

test9_2)

echo "I am test9_2.sh."

;;

*)

echo "You are illegal link file."

;;

esac

[root@wu 桌面]# ln -s test9.sh test9_2.sh

[root@wu 桌面]# ./test9_2.sh

test9_2

I am test9_2.sh.

三、编写一个更具可读性的df命令输出脚本

#!/bin/bash

#1. $$表示当前Shell进程的pid。

#2. trap信号捕捉是为了保证在Shell正常或异常退出时,仍然能够将该脚本创建的临时awk脚本文件删除。

awk_script_file="/tmp/scf_tmp.$$"

trap "rm -f $awk_script_file" EXIT

#3. 首先需要说明的是,'EOF'中的单引号非常重要,如果忽略他将无法通过编译,这是因为awk的命令动作必须要用单引号扩住。

#4. awk脚本的show函数中,int(mb * 100) / 100这个技巧是为了保证输出时保留小数点后两位。

cat < $awk_script_file

function show(size) {

mb = size / 1024;

int_mb = (int(mb * 100)) / 100;

gb = mb / 1024;

int_gb = (int(gb * 100)) / 100;

if (substr(size,1,1) !~ "[0-9]" || substr(size,2,1) !~ "[0-9]") {

return size;

} else if (mb 

return size "K";

} else if (gb 

return int_mb "M";

} else {

return int_gb "G";

}

}

#5. 在BEGIN块中打印重定义的输出头信息。

BEGIN {

printf "%-20s %7s %7s %7s %8s %s\n","FileSystem","Size","Used","Avail","Use%","Mounted"

}

#6. !/文件系统/ 表示过滤掉包含Filesystem的行,即df输出的第一行。其余行中,有个域字段可以直接使用df的输出,有的需要通过show函数的计算,以得到更为可读的显示结果。

!/文件系统/ {

size = show($2);

used = show($3);

avail = show($4);

printf "%-20s %7s %7s %7s %8s %s\n",$1,size,used,avail,$5,$6

}

EOF

df -k | awk -f $awk_script_file

[wulei@bogon 桌面]$ ./dd

FileSystem              Size    Used   Avail     Use% Mounted

/dev/sda2             17.45G   2.47G  14.09G      15% /

tmpfs                503.26M    232K 503.03M       1% /dev/shm

/dev/sda1            290.51M  31.03M 244.47M      12% /boot

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux shellLinux 操作系统中的一种命令行解释器,它是一种非常强大的工具,可以帮助用户完成各种任务。以下是一些 Linux shell 高阶技巧: 1. 使用命令替换:在 Linux shell 中,可以使用命令替换来获取命令的输出并将其作为另一个命令的参数。可以使用反引号或 $() 来实现命令替换。 2. 使用管道:管道是将一个命令的输出作为另一个命令的输入的一种方式。使用管道可以将多个命令链接在一起,以便更有效地处理数据。 3. 使用重定向:重定向是将命令的输出重定向到文件或另一个命令的输入的一种方式。可以使用 > 和 >> 将输出重定向到文件中,使用 < 将文件内容作为输入发送到命令中。 4. 使用通配符:通配符是一种匹配文件名模式的特殊字符。通配符可以用于查找文件、执行批量重命名等任务。 5. 使用别名:别名是一种将命令或命令串映射到另一个名称的方式。可以使用别名来简化常用命令的输入。 6. 使用 shell 脚本shell 脚本是一组 shell 命令的集合,可以自动执行一系列任务。可以使用 shell 脚本来自动化常见的任务,如备份、批处理等。 7. 使用条件语句和循环:条件语句和循环是 shell 脚本中的常见结构,可以根据条件执行不同的命令或重复执行一组命令。 8. 使用 awk 和 sed:awk 和 sed 是用于处理文本文件的命令行工具。它们提供了强大的文本处理功能,可以用于搜索、替换、过滤和格式化文本数据。 这些高级技巧可以帮助您更有效地使用 Linux shell,提高工作效率和生产力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值