主function execSteps逐个执行emerge --pretend $package,这些包的名称(只有名称,没有版本信息)存储在一个文本文件stepFile中。一些包可能需要额外配置package.use,package.license,在执行emerge --pretend $package之后会出现这种额外的信息。main函数中的第二个while循环和function acceptPKGTypeItems就是用来处理这种额外信息的。
当出现一个特定的包时,它可能依赖于更多的包。例如,emerge --pretend ceph,在ceph出现之前,我需要出现10个以上的包。随着Gentoo/Linux的更新,可能会应用新版本的包。所以文本文件stepFile只包含我需要的包名,并解析emerge --pretend $package的结果,我就能够得到更新包出现了。
在case 0),此while循环旨在解析emerge --pretend $line(which is from stepFile)的结果,例如emerge --pretend ceph,并获得其具有当前版本的依赖包,例如dev-libs/boost-1.57.0,将其作为参数传递给function emgRecursion,因为包ceph的依赖包dev-libs/boost-1.57.0可能有其自己的依赖包,即dev-libs/boost-build-1.57.0和dev-libs/boost-1.57.0。
我的问题是,当我在case 0)输入0时,我在function emgRecursion中得到了一个错误的while : command not found。这是另一种不同的shell吗?我在main函数中的第二个while循环之间添加了一对括号,这有助于用户在选择package.use、package.license或package.keywords时获得readin答案。我尝试在第三个while循环之间添加另一对括号,同样的问题。我已经分别测试了emgRecursion和acceptPKGTypeItems,它们都工作得很好并且正确。
有什么想法吗?非常感谢。
function acceptPKGTypeItems() {
...
}
function emgRecursion() {
local output="$(emerge --pretend "="$1 | grep "\[ebuild")"
while read -r line;
do
done <<<"$output"
}
function execSteps() {
local running=0
while read -r line;
do
if (( running )); then
if [[ $line = "#"* ]] && [[ "${line/"step"}" = "$line" ]]; then
continue
else
if [[ ! "${line/"step"}" = "$line" ]]; then
echo "====== approaching to the next step which is not available at this time."
break
else
( output="$(emerge --pretend $line | grep "\[ebuild")"
echo "**************** $line is ready for emerging ****************"
while read -p "Which type of package would you like to add new item to (1-packageuse 2-packagelicense 3-packagekeywords 0-exit and continue)? " choice; do
case "$choice" in
1) echo "**************** $line is ready for emerging"
acceptPKGTypeItems $PACKAGEUSE
echo "**************** package.use has been updated."
;;
2) echo "**************** $line is ready for emerging"
acceptPKGTypeItems $PACKAGELICENSE
echo "**************** package.license has been updated."
;;
3) echo "**************** $line is ready for emerging"
acceptPKGTypeItems $PACKAGEKEYWORDS
echo "**************** package.keywords has been updated."
;;
0) echo "**************** $line starts emerging"
while read -r element;
do
local str="${element#*"] "}"
str="${str%%" "*}"
echo " $str is an element that need to be emerged. "
emgRecursion "$str"
done <<<"$output"
echo "**************** $line has been emerged. ****************"
break
;;
*) echo "~~~~~~~~~~~~~~~~ Invalid input, try again. ~~~~~~~~~~~~~~~~"
;;
esac
done) </dev/tty
fi
fi
else
[[ $line = "#"$1 ]] && running=1
done <$STEPS
}
execSteps step2当在main函数中循环时,任何东西都不会停止,输出:
livecd / # ./step1
* Last emerge --sync was 32d 23h 4m 58s ago.
**************** sys-cluster/ceph is ready for emerging ****************
Which type of package would you like to add new item to (1-packageuse 2-packagelicense 3-package.keywords 0-exit and continue)?0
**************** sys-cluster/ceph starts emerging ****************
dev-libs/libaio-0.3.110 is an element that need to be emerged.
* Last emerge --sync was 32d 23h 5m 3s ago.
./step1: line 48: while: command not found
./step1: line 49: : command not found
./step1: line 50: str=dev-libs/libaio-0.3.110: No such file or directory
Take a look at what dev-libs/libaio-0.3.110 looks like.
./step1: line 77: done: command not found
sys-libs/libunwind-1.1 is an element that need to be emerged.
* Last emerge --sync was 32d 23h 5m 5s ago.
^C
Exiting on signal 2发布于 2015-11-25 01:22:05
在我创建用于测试emgRecursion的文件时,通过将emgRecursion以外的函数复制到另一个文件解决了这个问题。
我意识到这两个文件(recursion用于测试emgRecursion,step用于测试整个函数)之间的区别在于recursion最初是使用#!/bin/bash创建的,而step最初是一个没有任何第一行符号的纯shell文本文件,然后我在其中添加了#!/bin/bash。我认为bash文本文件和shell文本文件在语法上没有太大的区别。事实上,它们是完全不同的。如果你像我一样把它们混在一起,那就是浪费时间。
发布于 2015-11-24 07:31:41
这将是while循环的模板。如果你想读一整行,那就别费心在读取行中放一个变量,并且停止无用的单词拆分。
while read -r; do line=$REPLY ... done <<<"$OUTPUT"
请参阅Bash-Hackers
https://stackoverflow.com/questions/33882343
复制相似问题