声明! 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关,切勿触碰法律底线,否则后果自负!!!!有兴趣的小伙伴可以点击下面连接进入b站主页[B站泷羽sec](泷羽sec的个人空间-泷羽sec个人主页-哔哩哔哩视频)
本章课程链接:shell编程(完结)_哔哩哔哩_bilibili
重定向操作
基本概念
在 Shell 中,重定向是一种改变命令输入输出方向的机制。默认情况下,命令从标准输入(通常是键盘)获取输入,将输出发送到标准输出(通常是显示器),并且将错误信息发送到标准错误输出(也是显示器)。重定向可以让用户改变这些默认行为,比如将输出保存到文件、从文件读取输入或者将错误信息单独处理等。
标准输出重定向
>(覆盖输出)
例如,echo "Hello" > output.txt。这行命令会将echo命令输出的Hello字符串重定向到output.txt文件中。如果output.txt文件不存在,会创建一个新文件;如果文件已经存在,会覆盖文件中原有的内容。
>>(追加输出)
例如,echo "World" >> output.txt。当执行这个命令时,echo输出的World字符串会被追加到output.txt文件的末尾。如果文件不存在,同样会创建一个新文件。
标准输入重定向
<(从文件读取输入)
假设有xt个文件input.txt,内容为1 2 3,有一个命令read a b c < input.txt,这里read命令会从input.txt文件中读取内容,将文件中的三个数字分别赋值给变量a、b和c。
标准错误输出重定向
2>(覆盖错误输出)
例如,运行一个可能会出错的命令ls non - existent - directory 2> error.txt。因为non - existent - directory这个目录不存在,所以ls命令会产生错误信息。这些错误信息会被重定向到error.txt文件中,而不是在终端显示。如果error.txt文件不存在,会创建一个新文件;如果存在,则会覆盖文件中原有的内容。
2>>(追加错误输出)
类似于标准输出的追加重定向,2>>会将错误信息追加到指定文件的末尾。例如,command - that - may - error 2>> error.log,如果命令多次执行产生错误,每次的错误信息都会被追加到error.log文件中。
组合重定向
可以同时对标准输出和标准错误输出进行重定向。例如,command > output.txt 2> error.txt,这个命令会将命令command的正常输出保存到output.txt文件,将错误输出保存到error.txt文件。
还有一种更简洁的方式,&>或>&,可以将标准输出和标准错误输出同时重定向到同一个地方。例如,command &> combined_output.txt会将命令command的所有输出(包括正常输出和错误输出)都保存到combined_output.txt文件中。
不同的脚本互相调用
在 Shell 中调用另一个脚本的基本方法
点号(.)或source命令
语法:. script_name.sh或者source script_name.sh。
例如,有两个脚本script1.sh和script2.sh。如果想在script1.sh中调用script2.sh,可以在script1.sh中使用. script2.sh或者source script2.sh。这种方式会在当前 Shell 环境中执行script2.sh,这意味着script2.sh中定义的变量、函数等会被加载到当前 Shell 环境中,就好像这些内容是在script1.sh中直接定义的一样。
bash或sh命令(创建子进程执行)
语法:bash script_name.sh或者sh script_name.sh。
例如,在一个脚本main.sh中,可以通过bash sub_script.sh来调用sub_script.sh。这种方式会开启一个新的子进程来执行sub_script.sh,sub_script.sh中的变量和函数等在其执行完毕后通常不会影响主脚本main.sh的环境,因为它们是在不同的进程中运行的。不过,可以通过一些手段(如环境变量、文件等)来传递数据。
传递参数给被调用的脚本
当调用另一个脚本时,可以传递参数给它。在被调用的脚本中,参数的获取方式和在普通脚本中一样,通过$1、$2等变量来获取。
例如,在脚本caller.sh中有如下内容:
#!/bin/bash
./callee.sh arg1 arg2
在脚本callee.sh中可以通过$1获取arg1,通过$2获取arg2,就像这样:
#!/bin/bash
echo "The first argument received is: $1"
echo "The second argument received is: $2"
被调用脚本返回值的获取
在 Shell 中,脚本可以通过return命令返回一个整数值(通常用于表示执行状态,0 表示成功,非 0 表示失败)。在调用脚本中,可以使用$?变量来获取被调用脚本的返回值。
例如,在被调用脚本return_script.sh中有:
#!/bin/bash
# 模拟一个成功的操作并返回0
return 0
在调用脚本caller.sh中可以这样获取返回值:
#!/bin/bash
./return_script.sh
return_value=$?
echo "The return value of the called script is: $return_value"
脚本调用中的变量作用域和共享
如前面提到的,当使用.或source调用脚本时,变量是共享的,被调用脚本中的变量会影响调用脚本的环境。而使用bash或sh调用脚本时,变量默认是隔离的。
例如,使用.或source:
脚本script1.sh:
#!/bin/bash
var1=10
. script2.sh
echo "After calling script2.sh, var1 in script1.sh is: $var1"
脚本script2.sh:
#!/bin/bash
var1=20
运行script1.sh后,会发现输出的var1的值是 20,因为script2.sh中的变量定义影响了script1.sh的环境。
而如果使用bash调用:
脚本script1.sh:
#!/bin/bash
var1=10
bash script2.sh
echo "After calling script2.sh, var1 in script1.sh is: $var1"
脚本script2.sh(和上面一样):
#!/bin/bash
var1=20
文件描述符
0通常代表标准输入
1代表标准输出
2代表标准错误输出
基本概念
文件描述符是一个非负整数,用于在操作系统中标识一个打开的文件或者其他输入 / 输出资源。它是进程用来访问文件的抽象表示,在 Unix 和类 Unix 系统(包括 Linux)中广泛使用。可以把文件描述符想象成是进程和文件之间的一个 “通信桥梁”,进程通过这个数字来对文件进行各种操作,如读、写、关闭等。
标准输入(0)
它是进程用于读取输入的默认文件描述符。通常,这个输入来自键盘。例如,当运行一个命令,等待用户输入一些信息时,程序就是从标准输入(文件描述符为0)获取数据。在 Shell 脚本中,read命令就是从标准输入读取用户输入的内容,其底层就是通过文件描述符0来实现的。
标准输出(1)
这是进程用于输出信息的默认文件描述符。通常,输出会显示在终端屏幕上。例如,echo命令输出的内容就是通过标准输出(文件描述符1)发送到终端的。当使用重定向操作符>将输出重定向到一个文件时,实际上就是改变了文件描述符1的输出目标。
标准错误输出(2)
用于输出错误信息的文件描述符。和标准输出类似,但它专门用于显示错误消息,这样可以将正常输出和错误输出区分开来。例如,当运行一个命令,尝试访问一个不存在的文件时,产生的错误信息(如 “文件不存在”)就是通过标准错误输出(文件描述符2)发送的。可以使用2>或2>>来单独重定向标准错误输出。
自定义文件描述符(大于2)
除了标准的0、1、2这三个文件描述符外,进程可以打开更多的文件,并为它们分配自定义的文件描述符。这些自定义的文件描述符可以用于同时操作多个文件。例如,在一个程序中,可能同时打开了一个配置文件、一个数据文件和一个日志文件,分别为它们分配不同的文件描述符(如3、4、5等),然后通过这些文件描述符对不同的文件进行读写操作。在 Shell 中,也可以通过一些高级的重定向操作或者管道操作来利用这些自定义文件描述符,不过这种情况相对复杂一些。
实例
调用实例1
1 . vim 1.sh:
echo "hello word"
2. vim 2.sh
bash 1.sh
调用实例2
1. vim 1.sh
name="xiaoyu"
age=23
2. vim 2.sh
source 1.sh
echo "my name is $name and i am $age years old"
source:
命令的作用是在当前 Shell 环境下读取并执行 1.sh
这个脚本文件的内容。
重定向实例1输出重定向
vim 1.txt
ls > 1.txt
cat 1.txt
ls > 1.txt
操作说明:
ls 命令用于列出当前目录下的文件和目录信息。> 是标准输出重定向符号,它会将 ls 命令原本输出到终端的内容(即当前目录下的文件和目录列表)重定向到指定的文件 1.txt 中。如果 1.txt 不存在,会创建一个新文件;如果已经存在,会覆盖其原有内容。
cat 1.txt
操作说明:
cat 命令用于查看文件内容并输出到终端。这里是查看刚刚通过 ls > 1.txt 操作生成(或覆盖更新)的 1.txt 文件内容。
who > 1.txt
cat 1.txt
who > 1.txt
操作说明:
who 命令用于显示当前登录到系统的用户信息,包括用户名、终端设备、登录时间等。同样使用 > 进行标准输出重定向,将 who 命令输出的用户信息重定向到 1.txt 文件中,会覆盖掉之前 ls 操作在 1.txt 中存储的内容
追加>>
ls >>1.txt
cat 1.txt
ls >/dev/null 一般使用ls会有回显,但是重定向到这里,相当于垃圾箱,无回显
重定向实例2输入重定向1
1.创建目录到txt vim dir.txt
home/user/Documents
home/user/Picturas
home/user/Music
2. ls 结合输入重定向查看这些目录下的文件
ls -l < dir.txt
ls -l 是 ls 命令的一种常见用法,它会以长格式列出文件或目录的详细信息,包括文件类型、权限、所有者、所属组、文件大小、修改时间等。
< 是标准输入重定向符号。在这里,它使得 ls -l 命令不从默认的标准输入(通常是键盘)获取输入,而是从 dir.txt 文件中读取内容作为输入。也就是说,ls -l 会把 dir.txt 文件中的每一行内容都当作是一个文件名或目录名,然后尝试列出它们的详细信息。
在这个输出中:
drwxr-xr-x 表示文件类型(d 表示目录)和权限信息,这里表示所有者有读、写、执行权限,同组用户和其他用户有读和执行权限。
2 表示该目录下的硬链接数。
user 分别表示所有者和所属组都是 user。
4096 表示该目录所占的磁盘空间大小(以字节为单位,这里是一个常见的目录初始大小值)。
Dec 1 12:00 表示该目录的最后修改时间。
文件描述输出
如果输出正确,则输出到8.txt
ls > 8.txt 2> 9.txt
cat 8.txt
ls 命令用于列出当前目录下的文件和目录信息。
> 是标准输出重定向符号,ls > 8.txt 表示将 ls 命令的正常输出(即列出的文件和目录列表)重定向到 8.txt 文件中。如果 8.txt 不存在,会创建一个新文件;如果已经存在,会覆盖其原有内容。
2> 是标准错误输出重定向符号,ls > 8.txt 2> 9.txt 整体表示将 ls 命令的正常输出重定向到 8.txt 文件,同时将 ls 命令可能产生的错误输出(比如当试图列出一个不存在的目录或文件权限不足无法列出时产生的错误信息)重定向到 9.txt 文件。如果 9.txt 不存在,会创建一个新文件;如果存在,会覆盖其原有内容。
cat 命令用于查看文件内容并输出到终端。这里是查看刚刚通过 ls > 8.txt 操作生成(或覆盖更新)的 8.txt 文件内容。
如果输出错误则输出到9.txt
ABC > 8.txt 2> 9.txt
cat 9.txt
这里执行了一个重定向操作,但 “ABC” 不是一个有效的系统命令。
> 用于标准输出重定向,所以原本 “ABC” 命令的报错输出会被尝试重定向到 9.txt 文件中。如果 8.txt 不存在,会创建一个新文件;如果存在,会覆盖原有内容。
2> 用于标准错误输出重定向,这意味着 “ABC” 命令可能产生的错误输出会被重定向到 9.txt 文件。同样,如果 9.txt 不存在,会创建一个新文件;如果存在,会覆盖原有内容。
由于 “ABC”不是有效命令,执行这行操作通常会导致产生错误信息(比如在 bash shell 中可能会提示 “未找到命令” 之类的错误),而这些错误信息会按照重定向规则被发送到 9.txt 文件。