我遇到了一个奇怪的问题,不知道它来自哪里
我有2个类似的功能:
TMP_DIR="/tmp/folder"
OUTPUT_DIR="output"
func1()
{
for file in `ls $TMP_DIR/*_INPUT_VLAN.csv`
do
local hostname=$(echo $file | awk -F '_INPUT' '{print $1}' | cut -d "/" -f 4)
OUTPUT=$(echo $hostname"_net_conf.txt")
IFS=";"
cat $file | sed '1d' | while read f1 f2 f3 f4 f5 f6 f7 f8
do
echo "some things with $f1 $f2 .." >> $OUTPUT_DIR/$OUTPUT
done
done
}
func2()
{
for file in `ls $TMP_DIR/*_INPUT_ROUTES.csv`
do
local hostname=$(echo $file | awk -F '_INPUT' '{print $1}' | cut -d "/" -f 4)
OUTPUT=$(echo $hostname"_net_conf.txt")
IFS=";"
cat $file | sed '1d' | while read f1 f2 f3 f4
do
echo "some things with $f1 $f2 .." >> $OUTPUT_DIR/$OUTPUT
done
done
}
输入文件如下所示:
文件1:主机名1输入虚拟局域网. csv
int;type;vxid;name;id;ip;mask;comment
int1;int;0;vlan1;1;192.168.1.1;255.255.255.0;VLAN Network 1
int2;ext;1;vlan2;1;192.168.2.1;255.255.255.0;VLAN Network 2
int3;int;2;vlan3;1;192.168.3.1;255.255.255.0;VLAN Network 2
文件2:主机名2输入虚拟局域网. csv
int;type;vxid;name;id;ip;mask;comment
int1;int;0;vlan1;1;192.168.1.1;255.255.255.0;VLAN Network 1
int2;ext;1;vlan2;1;192.168.2.1;255.255.255.0;VLAN Network 2
int3;int;2;vlan3;1;192.168.3.1;255.255.255.0;VLAN Network 2
文件1:主机名1_INPUT_ROUTES.csv
Network;Interface;Gateway;Comment
0.0.0.0/0;int1;gateway1;Comment 1
net_1;int2;gateway2;Comment2
net_2;int2;gateway2;Comment2,1
net_3;int3;gateway3;Comment3
文件2:主机名2_INPUT_ROUTES.csv
Network;Interface;Gateway;Comment
0.0.0.0/0;int1;gateway1;Comment 1
net_1;int2;gateway2;Comment2
net_2;int2;gateway2;Comment2,1
net_3;int3;gateway3;Comment3
当我运行脚本时,第一个函数成功了,但第二个函数似乎没有执行for循环,而是尝试同时对两个文件执行cat操作:
cat: '/tmp/folder/HOSTNAME1_INPUT_ROUTES.csv'$'\n''/tmp/folder/HOSTNAME2_INPUT_ROUTES.csv': No such file or directory
如果我在函数中有一些回声来查看发生了什么,我会看到两个文件同时进行
func1()
{
for file in `ls $TMP_DIR/*_INPUT_VLAN.csv`
do
local hostname=$(echo $file | awk -F '_INPUT' '{print $1}' | cut -d "/" -f 4)
OUTPUT=$(echo $hostname"_net_conf.txt")
echo "Hostname for $file will be : $hostname"
echo "Ouput for $file will be located in : $OUTPUT_DIR/$OUTPUT"
done
}
function2()
{
for file in `ls $TMP_DIR/*_INPUT_ROUTES.csv`
do
local hostname=$(echo $file | awk -F '_INPUT' '{print $1}' | cut -d "/" -f 4)
OUTPUT=$(echo $hostname"_net_conf.txt")
echo "Hostname for $file will be : $hostname"
echo "Ouput for $file will be located in : $OUTPUT_DIR/$OUTPUT"
done
}
输出:
Hostname for /tmp/folder/HOSTNAME1_INPUT_VLAN.csv will be : HOSTNAME1
Ouput for /tmp/folder/HOSTNAME1_INPUT_VLAN.csv will be located in : output/HOSTNAME1_net_conf.txt
Hostname for /tmp/folder/HOSTNAME1_INPUT_ROUTES.csv
/tmp/folder/HOSTNAME2_INPUT_ROUTES.csv will be : HOSTNAME1
HOSTNAME2
Ouput for /tmp/folder/HOSTNAME1_INPUT_ROUTES.csv
/tmp/folder/HOSTNAME2_INPUT_ROUTES.csv will be located in : output/HOSTNAME1
HOSTNAME2_net_conf.txt
cat: '/tmp/folder/HOSTNAME1_INPUT_ROUTES.csv'$'\n''/tmp/folder/HOSTNAME2_INPUT_ROUTES.csv': No such file or directory
两个函数都用相同的why语句执行for循环,我不明白为什么func2不像excepted那样继续。
我找到了一个变通方案,方法是列出目录中的文件,存储在一个tmp文件中,然后使用while循环阅读该tmp文件,但我想知道为什么原始的for循环不起作用
预先感谢你的帮助
2条答案
按热度按时间xn1cxnb41#
func1
将IFS设置为;
,这样func2
中ls $TMP_DIR/*_INPUT_ROUTES.csv
的输出就不再在换行符上拆分。IFS控制如何执行单词拆分,所以在修改它时需要非常小心。一些一般性建议:
d7v8vwbk2#
此问题似乎与在第二个函数
func2()
的while
循环内的cat
命令中使用管道|
有关。管道创建了一个独立于主shell运行的子shell,在子shell中声明的任何变量在外部都不可用。
因此,
$OUTPUT
变量在 shell 程序中没有正确设置,并且不是重定向到具有预期名称的文件,而是重定向到具有两个$hostname
变量的名称并置的文件。要解决此问题,可以尝试在
cat
命令中将管道|
替换为<
,如下所示:这将重定向while循环的输入,使其来自
$file
指定的文件,而不是管道创建的子shell。此外,通常建议使用
$(command)
而不是反勾号进行命令替换,因此可以考虑将ls$TMP_DIR/*_INPUT_VLAN.csv
替换为$(ls $TMP_DIR/*_INPUT_VLAN.csv)
,对于其他使用反勾号的命令也是如此。希望有帮助