进行docker exec -it [container_id] /bin/bash
时:
我在下面运行了以下内容:
请假设文件夹test/data
存在。
root@6f200d5b9691: for file in $(aws s3 ls s3://foo-bucket | awk '{print $NF}') ; do aws s3 cp foo-bucket/${file} test/data && tar -xzf test/data/${file} -C test/data/ ; done
为此,我将所有文件放在相关路径下并提取了!
但是,当以这种方式通过shell进行完全相同的操作时:
root@6f200d5b9691: /bin/bash -ac "for file in $(aws s3 ls s3://foo-bucket | awk '{print $NF}') ; do aws s3 cp foo-bucket/${file} test/data && tar -xzf test/data/${file} -C test/data/ ; done"
我收到奇怪的错误,例如:
/bin/bash: -c: line 1: syntax error near unexpected token foo1.tar.gz'
/bin/bash: -c: line 1: foo1.tar.gz ; do aws s3 cp s3://foo-bucket/foo1.tar.gz 'test/data' && tar -xzf 'test/data/foo1.tar.gz' -C 'test/data/' ; done'
知道为什么会发生吗? 我在做什么错了?
第二个通过/bin/bash -ac "[commands here]"
运行的选项很重要,因为我想通过以下命令在命令中使用它:
docker-compose run [service_name] /bin/bash -ac "[...]"
答案 0 :(得分:3)
如果您运行
bash -c "file=foo; echo $file"
没有打印任何内容,因为$file
在bash -c
被看到之前被展开了(什么都没有)。
解决方案是使用单引号:
bash -c 'file=foo; echo "$file"'
现在,bash -c
看到整个参数都未修改。
对于您而言,这意味着
bash -ac 'for file in $(aws s3 ls s3://foo-bucket | awk "{print \$NF}"); do
aws s3 cp foo-bucket/"$file" test/data \
&& tar -xzf test/data/"$file" -C test/data/
done'
其中整个字符串都用单引号引起来。这样可以正确引用$file
;对于awk命令,我们必须转义$NF
,因为我们使用双引号。一种替代方法是
awk '\''{print $NF}'\''
将单引号包含在单引号中。
答案 1 :(得分:0)
$()和$ var解析。 因此$ file不会在新的bash中解析,而是在将字符串发送到bash之前解析。因此,我相信$ file在这种情况下将为空。