[email protected] parameters / cmd='sleep 5' [email protected] parame...">

当前位置:网站首页>shell eval用法详解 命令替换

shell eval用法详解 命令替换

2022-06-10 00:27:00 永远爱小芝芝~

一、命令替换

shell 脚本中经常需要使用命令替换,但是总是会出现各种各样的问题。

其实,我们可以通过 set -x进行 shell 语法的调试,以窥全貌。

示例如下:

[[email protected] parameters]# cmd="sleep 5"
[[email protected] parameters]# set -x
[[email protected] parameters]# `echo $cmd` # 1
++ echo sleep 5   							# 2 
+ sleep 5                                   # 3
[[email protected] parameters]# cmd="date" 
+ cmd=date
[[email protected] parameters]# `echo $cmd` # 4
++ echo date                                # 5
+ date                                      # 6
Mon May 30 17:40:44 CST 2022
[[email protected] parameters]# 

可以看到, #1 命令的解析过程如下面的 #2 和 #3,最后成功执行了命令;
同理,#4 命令的解析过程如下面的 #5 和 #6,最后成功执行了命令。

[[email protected] parameters]# cmd="date" 
+ cmd=date
[[email protected] parameters]# `$cmd` # 7
++ date						              	     # 8
+ Mon May 30 17:40:55 CST 2022                   # 9
+ local runcnf=1
+ local retval=127
+ [[ himxBH =~ i ]]
+ '[' '!' -S /var/run/dbus/system_bus_socket ']'
+ '[' '!' -x /usr/libexec/packagekitd ']'
+ '[' ']'
+ '[' 1 -eq 1 ']'
+ /usr/libexec/pk-command-not-found Mon May 30 17:40:55 CST 2022
bash: Mon: command not found...
+ retval=127
+ return 127
[[email protected] parameters]# 

可以看到, #7 命令的解析过程如下面的 #8 和 #9,最后 date 命令的输出结果又被解析为命令;于是发生了 shell 解析错误。


二、eval 命令

eval [arg ...]
              The args are read and concatenated together into a single command.  This command is then read and executed
              by the shell, and its exit status is returned as the value of eval.  If there are no args,  or  only  null
              arguments, eval returns 0.

可以看到,eval 命令用于读取参数并把参数拼接成一条命令。

[[email protected] parameters]# `eval echo $cmd`
++ eval echo date
+++ echo date
+ date
Mon May 30 17:57:24 CST 2022
[[email protected] parameters]# `echo $cmd` 
++ echo date
+ date
Mon May 30 17:57:43 CST 2022
[[email protected] parameters]# 

上面就是两条命令的解析过程。


三、命令的后台运行

假如我们有 n 个耗时的进程,并且进程执行的时间不确定。这时我们很难确定一个具体的时间来等待所有进程结束,同时让进程一个一个的运行显然也不现实。

这时我们就可以利用命令替换,将进程挂于后台运行,并等待进程退出。

[[email protected] platform]# vim demo.sh
#!/bin/bash


cmd1="sleep 10"
`eval echo $cmd1` &
CPLD_PROCESS[0]=$!

cmd2="sleep 10"
`eval echo $cmd2` &
CPLD_PROCESS[1]=$!


echo "===============1"
for((i=0;i<${#CPLD_PROCESS[*]};i++))
do
    echo "=============== start"
    echo ${CPLD_PROCESS[$i]}
    wait ${CPLD_PROCESS[$i]}
    echo "=============== finish"
done
echo "===============2"                                                                                                      
"demo.sh" [New] 21L, 345C written                                                                
[[email protected] platform]# chmod +x demo.sh 
"demo.sh" 21L, 345C written                                                                        
[[email protected] platform]# time ./demo.sh 
===============1
=============== start
6825
=============== finish
=============== start
6826
=============== finish
===============2

real    0m10.003s
user    0m0.000s
sys     0m0.004s
[[email protected] platform]# 

可以看到,执行多个10s休眠的进程,脚本也能让多个休眠同时后台运行,并及时退出脚本。

原网站

版权声明
本文为[永远爱小芝芝~]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_42109053/article/details/125051024