Linux 如何正确处理bashshell脚本中的通配符扩展?
上面是我提供的源(SRC)和设计(DEST)路径的shell脚本。当我没有将通配符“”放入SRC路径时,它工作得很好。当我运行此shell脚本并给出“”pdf或“*”时,如下所示:Linux 如何正确处理bashshell脚本中的通配符扩展?,linux,bash,unix,shell,Linux,Bash,Unix,Shell,上面是我提供的源(SRC)和设计(DEST)路径的shell脚本。当我没有将通配符“”放入SRC路径时,它工作得很好。当我运行此shell脚本并给出“”pdf或“*”时,如下所示: #!/bin/bash hello() { SRC=$1 DEST=$2 for IP in `cat /opt/ankit/configs/machine.configs` ; do echo $SRC | grep '*' > /dev/null
#!/bin/bash
hello()
{
SRC=$1
DEST=$2
for IP in `cat /opt/ankit/configs/machine.configs` ; do
echo $SRC | grep '*' > /dev/null
if test `echo $?` -eq 0 ; then
for STAR in $SRC ; do
echo -en "$IP"
echo -en "\n\t ARG1=$STAR ARG2=$2\n\n"
done
else
echo -en "$IP"
echo -en "\n\t ARG1=$SRC ARG2=$DEST\n\n"
fi
done
}
hello $1 $2
#!/bin/bash
hello() {
SRC=$1
DEST=$2
while read IP ; do
for FILE in $SRC; do
echo -e "$IP"
echo -e "\tARG1=$FILE ARG2=$DEST\n"
done
done < /tmp/machine.configs
}
hello "$1" $2
我得到以下输出:
root@ankit1:~/as_prac# ./test.sh /home/dev/Examples/*.pdf /ankit_test/as
DEST是/ankit_test/as,但由于“*”的原因,DEST也会被人工填充。预期的答案是
192.168.1.6
ARG1=/home/dev/Examples/case_Contact.pdf ARG2=/home/dev/Examples/case_howard_county_library.pdf
所以,如果你明白我想做什么,请帮助我解决这个错误。
我会感谢你的
提前感谢
我需要确切地知道如何在不干扰DEST的情况下在程序中逐个使用“*.pdf”。除非您转义通配符,否则shell将展开通配符,例如,如果您
ARG1=/home/dev/Examples/case_Contact.pdf ARG2=/ankit_test/as
并按以下方式运行脚本:
$ ls
one.pdf two.pdf three.pdf
这将是一样的
./test.sh *.pdf /ankit__test/as
这不是你所期望的。做
./test.sh one.pdf two.pdf three.pdf /ankit__test/as
应该可以工作。您还缺少关闭外部for循环的最终“完成”。无需生成shell来查看
$?
变量,您可以直接计算它
应该是:
./test.sh \*.pdf /ankit__test/as
你的脚本需要更多的工作。 即使在跳过通配符后,您也不会得到预期的答案。您将获得:
if [ $? -eq 0 ]; then
请尝试以下操作:
ARG1=/home/dev/Examples/*.pdf ARG2=/ankit__test/as
按如下方式运行:
for IP in `cat /opt/ankit/configs/machine.configs`
do
for i in $SRC
do
echo -en "$IP"
echo -en "\n\t ARG1=$i ARG2=$DEST\n\n"
done
done
好的,这似乎是您想要的:
root@ankit1:~/as_prac# ./test.sh "/home/dev/Examples/*.pdf" /ankit__test/as
./test.sh /ankit_test/as /home/dev/Examples/*.pdf
#/bin/bash
你好(){
SRC=$1
目的地=2美元
读IP时,请执行以下操作:
对于$SRC;do中的文件
echo-e“$IP”
echo-e“\tARG1=$FILE ARG2=$DEST\n”
完成
完成
hello
函数时,必须使用双引号,否则仅计算$1
就会导致通配符展开,但我们不希望在函数中分配$SRC
之前发生这种情况如果可以,请更改传递到shell脚本的参数的顺序,如下所示:
#!/bin/bash
hello()
{
SRC=$1
DEST=$2
for IP in `cat /opt/ankit/configs/machine.configs` ; do
echo $SRC | grep '*' > /dev/null
if test `echo $?` -eq 0 ; then
for STAR in $SRC ; do
echo -en "$IP"
echo -en "\n\t ARG1=$STAR ARG2=$2\n\n"
done
else
echo -en "$IP"
echo -en "\n\t ARG1=$SRC ARG2=$DEST\n\n"
fi
done
}
hello $1 $2
#!/bin/bash
hello() {
SRC=$1
DEST=$2
while read IP ; do
for FILE in $SRC; do
echo -e "$IP"
echo -e "\tARG1=$FILE ARG2=$DEST\n"
done
done < /tmp/machine.configs
}
hello "$1" $2
这将使你的生活更容易,因为可变部分移动到线的末端。然后,以下脚本将执行您想要的操作:
root@ankit1:~/as_prac# ./test.sh "/home/dev/Examples/*.pdf" /ankit__test/as
./test.sh /ankit_test/as /home/dev/Examples/*.pdf
以下是我的想法:
#!/bin/bash
hello()
{
SRC=$1
DEST=$2
for IP in `cat /opt/ankit/configs/machine.configs` ; do
echo -en "$IP"
echo -en "\n\t ARG1=$SRC ARG2=$DEST\n\n"
done
}
arg2=$1
shift
while [[ "$1" != "" ]] ; do
hello $1 $arg2
shift
done
我们将传入脚本获得的所有参数,而不是只向hello()函数传递两个参数
在hello()函数中,我们首先将最后一个参数分配给DEST变量,然后循环所有参数,将每个参数分配给SRC,并使用SRC和DEST参数运行我们想要的任何命令。请注意,如果$SRC和$DEST包含空格,您可能希望在它们周围加上引号。当SRC与DEST相同时,我们停止循环,因为这意味着我们已经到达了最终参数(目标)。您正在运行
#!/bin/bash
hello()
{
# DEST will contain the last argument
eval DEST=\$$#
while [ $1 != $DEST ]; do
SRC=$1
for IP in `cat /opt/ankit/configs/machine.configs`; do
echo -en "$IP"
echo -en "\n\t ARG1=$SRC ARG2=$DEST\n\n"
done
shift || break
done
}
hello $*
在脚本获取通配符之前,您的交互式shell正在扩展通配符。启动时只需引用第一个参数,如中所示
./test.sh /home/dev/Examples/*.pdf /ankit_test/as
然后,在您的脚本中,在您希望使用通配符的任何地方引用“$SRC”(即,当您使用
echo$SRC
,而不是使用echo“$SRC”
),并在您希望扩展通配符时将其保留为不带引号。基本上,除非您希望解释元字符,否则始终在可能包含shell元字符的内容周围加引号。:) 对于使用通配符(如*.txt)的多个输入文件,我发现这非常有效,不需要转义。它应该像“ls”或“rm”这样的本地bash应用程序一样工作。这几乎在任何地方都没有记录,因此,由于我花了3天的大部分时间试图弄清楚它,我决定将其发布给未来的读者
目录包含以下文件(ls的输出)
像脚本一样运行
file1.txt file2.txt file3.txt
甚至像
$ ./script.sh *.txt
剧本
$ ./script.sh file{1..3}.txt
关键是暂时切换IFS(内部字段分隔符)。您必须确保在切换之前存储该文件,然后在完成上述操作后将其切换回
现在,您在file[]数组中有了一个扩展文件列表(,其中转义了空格)),您可以在其中循环。我喜欢这个解决方案,因为它是最好的、最容易编程的,对用户来说也是最容易的。你说得对,但我想逐一使用所有的“one.pdf、two.pdf、three.pdf”。例如,我需要将这一切复制到另一个位置。那么wat就是解决方案。请帮助我。我在shell脚本方面没有太多经验。所以,我不知道这是一种奇怪的使用方式。我也试过你的,但有以下错误。当使用此./test.sh:line 14:[:missing`]'p.s.时出现此错误。此版本仅使用shell内置程序,因此不需要生成任何子进程来完成其工作。