vieyahn2017 / shellv

shell command test and study
4 stars 1 forks source link

【3.24】shell的exec #84

Open vieyahn2017 opened 1 year ago

vieyahn2017 commented 1 year ago

shell 中的 exec 两种用法:

1.exec 命令 ;命令代替shell程序,命令退出,shell 退出;比如 exec ls

2.exec 文件重定向,可以将文件的重定向就看为是shell程序的文件重定向 比如 exec 5</dev/null;exec 5<&-

=============================

shell的内建命令exec将并不启动新的shell,而是用要被执行命令替换当前的shell进程,并且将老进程的环境清理掉,而且exec命令后的其它命令将不再执行。 因此,如果你在一个shell里面,执行exec ls那么,当列出了当前目录后,这个shell就自己退出了,因为这个shell进程已被替换为仅仅执行ls命令的一个进程,执行结束自然也就退出了。为了避免这个影响我们的使用,一般将exec命令放到一个shell脚本里面,用主脚本调用这个脚本,调用点处可以用bash a.sh,(a.sh就是存放该命令的脚本),这样会为a.sh建立一个sub shell去执行,当执行到exec后,该子脚本进程就被替换成了相应的exec的命令。 source命令或者".",不会为脚本新建shell,而只是将脚本包含的命令在当前shell执行。 不过,要注意一个例外,当exec命令来对文件描述符操作的时候,就不会替换shell,而且操作完成后,还会继续执行接下来的命令。 exec 3<&0:这个命令就是将操作符3也指向标准输入。

另外,这个命令还可以作为find命令的一个选项,如下所示: (1)在当前目录下(包含子目录),查找所有txt文件并找出含有字符串"bin"的行 find ./ -name ".txt" -exec grep "bin" {} \; (2)在当前目录下(包含子目录),删除所有txt文件 find ./ -name ".txt" -exec rm {} \;

先总结一个表:

exec命令 作用

exec ls 在shell中执行ls,ls结束后不返回原来的shell中了

exec <file 将file中的内容作为exec的标准输入

exec >file 将file中的内容作为标准写出

exec 3<file 将file读入到fd3中

sort <&3 fd3中读入的内容被分类

exec 4>file 将写入fd4中的内容写入file中

ls >&4 Ls将不会有显示,直接写入fd4中了,即上面的file中

exec 5<&4 创建fd4的拷贝fd5

exec 3<&- 关闭fd3 ———————————————— 版权声明:本文为CSDN博主「再闹东海7」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_31186123/article/details/82190776

vieyahn2017 commented 1 year ago

“<<<”同样是一种特殊重定向,但是它的右侧是一个字符串。

下面是一个典型例子:

passwd --stdin root <<< "123456"

实现了用脚本修改密码(非交互形式修改密码)

这个功能的另一种实现是通过管道形式:echo "123456" | passwd --stdin root

vieyahn2017 commented 1 year ago

以前抄的代码都没细究


pass_phase=$(genSslPwd)

function genRestfulCA()
{
    pem_name=tomcat

    echo "Generating key for $ou_member"
    exec 3<<<${pass_phase}
    openssl genrsa -aes256 -out ${pem_name}.key  -passout fd:3 2048
    exec 3<<<${pass_phase}
    openssl req -sha256 -new -days $valid_days -key ${pem_name}.key -out ${pem_name}.csr -subj "$cn_prefix/OU=$ou_member/CN=Huawei"  -passin fd:3
    exec 3<<<${pass_phase}
    # 签发的restful证书keystore.p12和CA证书roo-ca.crt是独立自签的,两者没有证书链关系。所以客户端信任root-ca.crt之后并不能通过校验;应该是由root-ca.crt去签发keystore.p12
    openssl ca -batch -name SigningCA -cert RootCA/root-ca.crt -keyfile RootCA/root-ca.key -config root-ca.cfg -startdate "${caStartdate}" -passin fd:3 -extensions v3_ca -out ${pem_name}.crt -infiles ${pem_name}.csr
    cat ${pem_name}.crt ${pem_name}.key > ${pem_name}.pem
    echo "Generate java cert"
    exec 3<<<${pass_phase}
    exec 4<<<${pass_phase}
    openssl pkcs12 -export -in ${pem_name}.crt -inkey ${pem_name}.key -out ${pem_name}.p12 -name "${pem_name}" -passout fd:3 -passin fd:4

    cp ${pem_name}.p12 keystore.p12
}
vieyahn2017 commented 1 year ago

linux-oEjgch:/home # echo $$ 2120049 linux-oEjgch:/home # ll /proc/$$/fd total 0 lrwx------ 1 root root 64 Mar 24 17:46 0 -> /dev/pts/9 lrwx------ 1 root root 64 Mar 24 17:46 1 -> /dev/pts/9 lrwx------ 1 root root 64 Mar 24 17:46 2 -> /dev/pts/9 lrwx------ 1 root root 64 Mar 24 17:46 255 -> /dev/pts/9

linux-oEjgch:/home # pass_phase="passwd_TEST_xxxxx" linux-oEjgch:/home # exec 3<<<${pass_phase} linux-oEjgch:/home # linux-oEjgch:/home # ll /proc/$$/fd total 0 lrwx------ 1 root root 64 Mar 24 17:46 0 -> /dev/pts/9 lrwx------ 1 root root 64 Mar 24 17:46 1 -> /dev/pts/9 lrwx------ 1 root root 64 Mar 24 17:46 2 -> /dev/pts/9 lrwx------ 1 root root 64 Mar 24 17:46 255 -> /dev/pts/9 lr-x------ 1 root root 64 Mar 24 17:55 3 -> '/tmp/sh-thd.ml9nai (deleted)'

linux-oEjgch:/home # ls >&3 ls: write error: Bad file descriptor linux-oEjgch:/home # exec 3>file3 # 将写入fd3中的内容写入file中

linux-oEjgch:/home # ll /proc/$$/fd total 0 lrwx------ 1 root root 64 Mar 24 17:46 0 -> /dev/pts/9 lrwx------ 1 root root 64 Mar 24 17:46 1 -> /dev/pts/9 lrwx------ 1 root root 64 Mar 24 17:46 2 -> /dev/pts/9 lrwx------ 1 root root 64 Mar 24 17:46 255 -> /dev/pts/9 l-wx------ 1 root root 64 Mar 24 17:55 3 -> /home/file3

linux-oEjgch:/home # ls >&3 linux-oEjgch:/home # echo $$ >&3 linux-oEjgch:/home # exec 3<&- # 关闭fd3

linux-oEjgch:/home # ll /proc/$$/fd total 0 lrwx------ 1 root root 64 Mar 24 17:46 0 -> /dev/pts/9 lrwx------ 1 root root 64 Mar 24 17:46 1 -> /dev/pts/9 lrwx------ 1 root root 64 Mar 24 17:46 2 -> /dev/pts/9 lrwx------ 1 root root 64 Mar 24 17:46 255 -> /dev/pts/9

linux-oEjgch:/home # cat /home/file3 ddd file3 2120049

这样只测了fd和exec的重定向 其实没测到 <<<

vieyahn2017 commented 1 year ago

linux-oEjgch:/home # echo 123456789 > file5 linux-oEjgch:/home # exec 5<> file5 linux-oEjgch:/home # ll /proc/$$/fd total 0 lrwx------ 1 root root 64 Mar 24 17:46 0 -> /dev/pts/9 lrwx------ 1 root root 64 Mar 24 17:46 1 -> /dev/pts/9 lrwx------ 1 root root 64 Mar 24 17:46 2 -> /dev/pts/9 lrwx------ 1 root root 64 Mar 24 17:46 255 -> /dev/pts/9 lrwx------ 1 root root 64 Mar 24 19:40 5 -> /home/file5

linux-oEjgch:/home # read -n 4 <&5 linux-oEjgch:/home # echo -n . >&5 linux-oEjgch:/home # exec 5>&- linux-oEjgch:/home # cat file5 1234.6789

vieyahn2017 commented 1 year ago

终于测到了 <<<

linux-oEjgch:/home # pass_phase="passwd_TEST_xxxxx" linux-oEjgch:/home # exec 3<<<${pass_phase} linux-oEjgch:/home # read ppp <&3 linux-oEjgch:/home # echo $ppp passwd_TEST_xxxxx linux-oEjgch:/home # exec 3<&-

linux-oEjgch:/home # exec 3<<<${pass_phase} linux-oEjgch:/home # ll /proc/$$/fd total 0 lrwx------ 1 root root 64 Mar 24 17:46 0 -> /dev/pts/9 lrwx------ 1 root root 64 Mar 24 17:46 1 -> /dev/pts/9 lrwx------ 1 root root 64 Mar 24 17:46 2 -> /dev/pts/9 lrwx------ 1 root root 64 Mar 24 17:46 255 -> /dev/pts/9 lr-x------ 1 root root 64 Mar 24 17:55 3 -> '/tmp/sh-thd.mSuX8Y (deleted)' linux-oEjgch:/home # read -N 5 ppp <&3 linux-oEjgch:/home # echo $ppp passw linux-oEjgch:/home # read -N 5 ppp <&3 linux-oEjgch:/home # echo $ppp d_TES linux-oEjgch:/home # read -N 5 ppp <&3 linux-oEjgch:/home # echo $ppp T_xxx linux-oEjgch:/home # read -N 5 ppp <&3 linux-oEjgch:/home # echo $ppp xx linux-oEjgch:/home # exec 3<&-

linux-oEjgch:/home # exec 3<<<${pass_phase} linux-oEjgch:/home # read -n 5 ppp <&3 linux-oEjgch:/home # echo $ppp passw linux-oEjgch:/home # read -n 5 ppp <&3; echo $ppp d_TES linux-oEjgch:/home # read -n 5 ppp <&3; echo $ppp T_xxx linux-oEjgch:/home # read -n 5 ppp <&3; echo $ppp xx linux-oEjgch:/home # read -n 5 ppp <&3; echo $ppp

linux-oEjgch:/home # exec 3<&-

-N和-n都可以

vieyahn2017 commented 1 year ago

linux-oEjgch:/home # exec 3<<<${pass_phase} linux-oEjgch:/home # cat /proc/$$/fdinfo/3 pos: 0 flags: 0100000 mnt_id: 117 linux-oEjgch:/home # read -n 5 ppp <&3; echo $ppp passw linux-oEjgch:/home # cat /proc/$$/fdinfo/3 pos: 5 flags: 0100000 mnt_id: 117 linux-oEjgch:/home # read -n 5 ppp <&3; echo $ppp d_TES linux-oEjgch:/home # cat /proc/$$/fdinfo/3 pos: 10 flags: 0100000 mnt_id: 117 linux-oEjgch:/home # read -n 5 ppp <&3; echo $ppp T_xxx linux-oEjgch:/home # cat /proc/$$/fdinfo/3 pos: 15 flags: 0100000 mnt_id: 117 linux-oEjgch:/home # read -n 5 ppp <&3; echo $ppp xx linux-oEjgch:/home # cat /proc/$$/fdinfo/3 pos: 18 flags: 0100000 mnt_id: 117 linux-oEjgch:/home # read -n 5 ppp <&3; echo $ppp

linux-oEjgch:/home # cat /proc/$$/fdinfo/3 pos: 18 flags: 0100000 mnt_id: 117

vieyahn2017 commented 1 year ago

简单的是这样

linux-oEjgch:/home # exec 3<<<${pass_phase} linux-oEjgch:/home # read -u 3 a linux-oEjgch:/home # echo $a passwd_TEST_xxxxx linux-oEjgch:/home # exec 3<&-