此bash脚本将jar文件的名称连接到类路径(变量CP),在while循环中值正确但在子shell中丢失,如此相关问题中所述Bash variable scope
#!/bin/bash
CP="AAA"
func() {
ls -1 | while read JAR
do
if [ ! -z "$CP" ]; then
CP=${CP}':'
fi
CP=${CP}${JAR}
done
echo $CP # <-- prints AAA
}
func
我的问题是,由于我无法确定哪个元素将是最后一个元素,如何保存该值。
我是否真的必须将当前值(在循环中重复出现)保存到文件中?
编辑:
一位同事提出了这个命令序列,效果很好
ls | xargs echo|tr ' ' :
答案 0 :(得分:6)
这里的问题是在管道中使用while
会创建子shell,而子shell不会影响其父级。你可以通过几种方式解决这个问题。对于你现在正在做的事情,这就足够了:
for JAR in *; do
# Your stuff
done
另外需要注意的是shouldn't rely on parsing ls
This还会向您展示避免子shell的方法。
答案 1 :(得分:1)
您可能会发现使用find更具通用性。
例如:
export CP=$( find /home/depesz/q/ -maxdepth 1 -type f -name '*.jar' -printf ':%p' | cut -b 2- )
当然,查找选项集取决于您需要/想要的内容。
这个更接近您之前的情况:
export CP=$( find . -maxdepth 1 -type f -name '*.jar' -printf ':%f' | cut -b 2- )
答案 2 :(得分:0)
隐含的子弹令人困惑;总是通过使用括号使它们明确。要解决您的问题,只需在子shell中移动回显。
#!/bin/bash
CP="AAA"
func() {
ls -1 | (
while read JAR
do
if [ ! -z "$CP" ]; then
CP=${CP}':'
fi
CP=${CP}${JAR}
done
echo $CP
)
}
func
答案 3 :(得分:0)
这是另一种解决方案,它可以完全避免产生子shell。关键是将循环输入捕获到变量中(在我的示例中称为“JARS”),然后使用&lt;&lt;&lt;&lt; EOF:
JARS=$(ls -1)
while read JAR
do
if [ ! -z "$CP" ]; then
CP=${CP}':'
fi
CP=${CP}${JAR}
done <<EOF
$JARS
EOF
echo $CP
答案 4 :(得分:0)
这些答案似乎都没有真正实际返回正确的值,通过一个非常简单的例程回答答案很好,但是说你想要输出脚本,这是没用的。我没有最好的答案,但我没有太多时间来弄清楚,所以我只是建议输出你想要的临时文件并读取它(惊讶它没有到目前为止提到):
#!/bin/bash
CP="AAA"
func() {
ls -1 | (
while read JAR
do
if [ ! -z "$CP" ]; then
CP=${CP}':'
fi
CP=${CP}${JAR}
done
echo "$CP" > /tmp/cp-value-file
)
}
func
CP=$(cat /tmp/cp-value-file)
echo $CP
下行:在某些情况下,每次迭代都需要写入磁盘。