我正在尝试使用标志为我的bash程序设置输出文件。如果我没有明确输入使用stdout的参数,我想使其成为可能。另外,我设置了迭代次数。如果我不提供此标志,请将其设置为3。
这就是我所拥有的:
while getopts i:o: option
do
case "${option}"
in
i) ITERATIONS=${OPTARG};;
o) OUTPUTF=${OPTARG};;
esac
done
docker-compose up -d
for i in {1..ITERATIONS}
do docker-compose run specs | tee OUTPUTF
sleep 1
done
docker-compose stop
答案 0 :(得分:4)
默认值很容易;只需在while
循环之前分配它们即可。如果循环从不覆盖该值,则它们将保留默认值。
棘手的部分是找出OUTPUTF
的适当默认值。如果文件系统公开,则可以使用/dev/stdout
,也可以使用/dev/fd/0
,但实际上并没有可以使用的标准名称。
作为替代方案,我建议将docker-compose
的输出传递给一个函数,该函数的定义可能取决于对-o
选项的使用。
iterations=3
log_output () { cat; } # Meant to ignore its argument
outputf= # default value doesn't really matter
while getopts i:o: option; do
case $option in
i) iterations=$OPTARG ;;
o) log_output () { tee "$1"; }
outputf=$OPTARG
;;
esac
done
docker-compose up -d
for ((i=0; i < $iterations; i++)); do # Can't use parameters in a brace expression
docker-compose run specs
sleep 1
done | log_output "$outputf"
docker-compose stop
默认情况下,log_output
仅将其输入传递给cat
,而忽略其参数。如果使用-o
,则log_output
被重新定义为tee
的包装器,并保存输出文件名。无论哪种方式,都以log_output
作为参数来调用"$outputf"
。
答案 1 :(得分:1)
如果您希望迭代具有默认值,则可以在case语句之前将其设置为默认值,例如declare -i ITERATIONS=3;
。
如果我正确理解了问题的第一部分,那么您还可以选择将输出也写入文件(如果提供给bash脚本),对吗?如果是这样,有很多方法可以执行此操作,但是我认为一个简单的解决方案是将OUTPUTF
默认设置为/dev/null
并覆盖提供的输出路径。
结果如下:
declare -i ITERATIONS=3;
declare OUTPUTF=/dev/null;
while getopts i:o: option; do
case "${option}" in
i) ITERATIONS="${OPTARG}";;
o) OUTPUTF="${OPTARG}";;
esac
done
docker-compose up -d
for i in {1..ITERATIONS}; do
docker-compose run specs
sleep 1
done | tee "$OUTPUTF"
docker-compose stop
值得注意的是,我将tee
移到了for循环的外部,因为否则将产生一个新进程,并且每次迭代都将覆盖输出文件。