我有这个脚本,名为Compare.sh
:
function Compare()
{
echo 'Comparing here'
}
while read Dependency; do
Org=$(echo $Dependency | cut -d'/' -f1)
Repo=$(echo $Dependency | cut -d'/' -f2)
echo "Comparing $Repo ...";
Compare $Repo
done <<< "$({ cat "$PWD/Dependencies"; echo; })"
的内容Dependencies
是依赖列表
Infra/Logging
Infra/Geo
Infra/Accounts
Company/Services
Company/Employees
我这样称呼这个函数./Compare.sh
,它读取Dependencies
文件并循环遍历它。
但是,现在我希望能够只给它一项作为参数。./Compare.sh Infra/Accounts
。如果提供了参数,我希望循环使用它,基本上,它只循环一次。否则,它应该读取该Dependencies
文件。
伪代码:
done <<< if $1 then $1 else "$({ cat "$PWD/Dependencies"; echo; })"
这可能吗?
答案1
一种方法是根本不理会脚本中的文件:
#!/bin/bash
Compare () {
# some code
}
while IFS=/ read -r Org Repo || [ -n "$Repo" ]; do
printf 'Comparing "%s"\n' "$Repo"
Compare "$Repo"
done
你可以这样称呼它:
$ ./script <Dependencies
或者像这样:
$ ./script <<<"Infra/Accounts"
或者像这样:
$ some-command | ./script
或者像这样:
$ ./script <<'END'
some/data
more/stuff
last/line
END
或以许多类似的方式。
此脚本中的循环将前两个/
- 分隔字符串读取到变量中Org
并Repo
从脚本的标准输入流中读取(Repo
将获取该行的其余部分,即使/
那里还有更多 - 字符,添加一个虚拟变量以避免这种情况)。由用户决定在输入流上传递他们想要处理的数据,脚本本身并不关心这是如何完成的。
-n
如果您传递一个最后一行未终止的文件(这似乎是您试图通过向问题中的脚本提供数据的方式来确保的echo
),则进行测试。
如果你想读取某个文件Dependencies
,默认情况下,并且仅使用命令行参数作为数据(如果给出了这些参数),然后使用
#!/bin/bash
Compare () {
# some code
}
if [ "$#" -eq 0 ]; then
cat Dependencies
else
printf '%s\n' "$@"
fi |
while IFS=/ read -r Org Repo || [ -n "$Repo" ]; do
printf 'Comparing "%s"\n' "$Repo"
Compare "$Repo"
done
也就是说,cat
如果没有命令行参数,则显示该文件,否则在单独的行上打印命令行参数。无论完成哪件事,该if
语句都会向与解决方案的第一个变体中相同的循环提供输入。
您可以将此脚本用作
$ ./script
或作为
$ ./script 'some/data' 'more/stuff' 'last/line'
请注意,第二个脚本可以编写为第一个脚本的包装器script1
:
#!/bin/sh
if [ "$#" -eq 0 ]; then
cat Dependencies
else
printf '%s\n' "$@"
fi |
./script1
答案2
这可能吗?
也许,使用(man bash)“参数扩展;使用默认值”和“命令替换”。尝试像
for Dependency in ${1:-$(< Dependencies)}
do echo $Dependency
done