OnWorks Linux 和 Windows 在线工作站

商标

工作站免费在线托管

<上一页 | 内容 | 下一页>

组命令和子shell

打坏 允许将命令组合在一起。 这可以通过以下两种方式之一完成; 或者 组命令 或与 子壳. 以下是每个语法的示例:

组命令:

{命令1; 命令2; [命令3; ...] }

子外壳:

(命令 1;命令 2;[命令 3;...])

这两种形式的区别在于组命令用大括号将其命令括起来,而子shell 使用括号。 需要注意的是,由于方式 打坏 实现组命令,大括号必须用空格与命令分开,最后一个命令必须在右大括号之前以分号或换行符结束。

那么组命令和子shell 有什么用呢? 虽然它们有一个重要的区别(我们稍后会谈到),但它们都用于管理重定向。 让我们考虑一个对多个命令执行重定向的脚本段:



ls -l > 输出.txt

echo "foo.txt 列表" >> output.txt cat foo.txt >> output.txt

ls -l > 输出.txt

echo "foo.txt 列表" >> output.txt cat foo.txt >> output.txt


这很简单。 三个命令的输出重定向到一个名为 输出.txt. 使用 group 命令,我们可以这样编码:


{ ls -l; echo "foo.txt 列表"; 猫 foo.txt; } > 输出.txt

{ ls -l; echo "foo.txt 列表"; 猫 foo.txt; } > 输出.txt


使用子shell是类似的:



(ls -l; echo "Listing of foo.txt"; cat foo.txt) > output.txt

(ls -l; echo "Listing of foo.txt"; cat foo.txt) > output.txt


使用这种技术我们可以节省一些输入,但是组命令或子 shell 真正闪耀的地方是管道。 在构建命令管道时,将多个命令的结果组合到单个流中通常很有用。 组命令和子 shell 使这变得容易:



{ ls -l; echo "foo.txt 列表"; 猫 foo.txt; } | 流量

{ ls -l; echo "foo.txt 列表"; 猫 foo.txt; } | 流量


在这里,我们组合了三个命令的输出并将它们通过管道传输到 LPR 生成打印报告。

在接下来的脚本中,我们将使用组命令并查看可以与关联数组结合使用的几种编程技术。 这个脚本叫做 阵列 2, 当给定目录名称时,打印目录中文件的列表以及文件所有者和组所有者的名称。 在列表的末尾,脚本会打印属于每个所有者和组的文件数。 在这里,我们看到脚本被赋予目录时的结果(为简洁起见而进行了压缩)

/usr/bin:


[我@linuxbox ~]$ 阵列 2 /usr/bin

/usr/bin/2to3-2.6

/usr/bin/2to3

/usr/bin/a2p

/usr/bin/浏览器

/usr/bin/连接

/usr/bin/acpi_fakekey

/usr/bin/acpi_listen

/usr/bin/add-apt-存储库

.

.

.

/usr/bin/zipgrep

/usr/bin/压缩信息

/usr/bin/zipnote

/usr/bin/zip


/usr/bin/zipsplit

/usr/bin/zjsdecode

/usr/bin/zsoelim

根根根

根根根

文件所有者:守护进程:1


文件(S)

根:1394

文件(S)

图片

文件组所有者:crontab:1 个文件守护程序:1 个文件 lpadmin:1 个文件 mail:4 个文件 mlocate:1 个文件 root:1380 个文件 shadow:2 个文件(s) ssh : 1 个文件

tty : 2 个文件

utmp : 2 个文件


图片

#!/斌/庆典

#!/斌/庆典

# array-2:使用数组来统计文件所有者

如果 [[ ! -d "$1" ]]; 然后

echo "用法:array-2 目录" >&2 exit 1

fi


因为我在“$1”/*; do owner=$(stat -c %U "$i") group=$(stat -c %G "$i") files["$i"]="$i" file_owner["$i"]=$ owner file_group["$i"]=$group ((++owners[$owner])) ((++groups[$group]))

完成


# 列出收集到的文件

{ for i in "${files[@]}"; 做 printf "%-40s %-10s %-10s\n" \

"$i" ${file_owner["$i"]} ${file_group["$i"]} 完成 } | 种类

# array-2:使用数组来统计文件所有者

如果 [[ ! -d "$1" ]]; 然后

echo "用法:array-2 目录" >&2 exit 1

fi


因为我在“$1”/*; do owner=$(stat -c %U "$i") group=$(stat -c %G "$i") files["$i"]="$i" file_owner["$i"]=$ owner file_group["$i"]=$group ((++owners[$owner])) ((++groups[$group]))

完成


# 列出收集到的文件

{ for i in "${files[@]}"; 做 printf "%-40s %-10s %-10s\n" \

"$i" ${file_owner["$i"]} ${file_group["$i"]} 完成 } | 种类

这是脚本的列表(带有行号):


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26


27

28

29

30

31

32

33

34

35

36

37

38

39

40

27

28

29

30

31

32

33

34

35

36

37

38

39

40


图片

回音

回音

# 列出所有者

echo "文件所有者:"

{ for i in "${!owners[@]}"; 做

printf "%-10s: %5d 个文件\n" "$i" ${owners["$i"]} done } | 种类

回音


# 列出组

echo "文件组所有者:"

{ for i in "${!groups[@]}"; 做

printf "%-10s: %5d 个文件\n" "$i" ${groups["$i"]} 完成 } | 种类

# 列出所有者

echo "文件所有者:"

{ for i in "${!owners[@]}"; 做

printf "%-10s: %5d 个文件\n" "$i" ${owners["$i"]} done } | 种类

回音


# 列出组

echo "文件组所有者:"

{ for i in "${!groups[@]}"; 做

printf "%-10s: %5d 个文件\n" "$i" ${groups["$i"]} 完成 } | 种类

让我们来看看这个脚本的机制:

线5: 关联数组必须使用 宣布 使用命令 -A

选项。 在这个脚本中,我们创建了五个数组,如下所示:

files 包含目录中文件的名称,按文件名索引 file_group 包含每个文件的组所有者,按文件名索引 file_owner 包含每个文件的所有者,按文件名索引groups 包含属于索引组所有者的文件数包含属于索引所有者的文件数

第 7-10 行:检查是否将有效的目录名称作为位置参数传递。 如果不是,则会显示一条用法消息,并且脚本以退出状态 1 退出。

第 12-20 行: 循环遍历目录中的文件。 使用 统计 命令,第 13 和 14 行提取文件所有者和组所有者的名称,并使用文件名作为数组索引将值分配给它们各自的数组(第 16、17 行)。 同样,文件名本身被分配给 数组(第 15 行)。

第 18-19 行:属于文件所有者和组所有者的文件总数加 XNUMX。

第 22-27 行: 输出文件列表。 这是使用“${array[@]}”参数扩展完成的,该参数扩展扩展为整个数组元素列表,每个元素都被视为一个单独的词。 这允许文件名可能包含嵌入的空格。 还要注意整个循环都用大括号括起来,从而形成一个组命令。 这允许循环的整个输出通过管道传输到 分类 命令。 这是必要的,因为数组元素的扩展没有排序。

第 29-40 行:这两个循环与文件列表循环相似,只是它们使用了“${!


array[@]}" 扩展,它扩展到数组索引列表而不是数组元素列表。


 

OnWorks 的顶级操作系统云计算: