首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >嵌套函数和while循环在bash中返回`while: command not found`

嵌套函数和while循环在bash中返回`while: command not found`
EN

Stack Overflow用户
提问于 2015-11-24 06:57:19
回答 2查看 497关注 0票数 2

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.0dev-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循环之间添加另一对括号,同样的问题。我已经分别测试了emgRecursionacceptPKGTypeItems,它们都工作得很好并且正确。

有什么想法吗?非常感谢。

代码语言:javascript
复制
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函数中循环时,任何东西都不会停止,输出:

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

发布于 2015-11-25 01:22:05

在我创建用于测试emgRecursion的文件时,通过将emgRecursion以外的函数复制到另一个文件解决了这个问题。

我意识到这两个文件(recursion用于测试emgRecursionstep用于测试整个函数)之间的区别在于recursion最初是使用#!/bin/bash创建的,而step最初是一个没有任何第一行符号的纯shell文本文件,然后我在其中添加了#!/bin/bash。我认为bash文本文件和shell文本文件在语法上没有太大的区别。事实上,它们是完全不同的。如果你像我一样把它们混在一起,那就是浪费时间。

票数 0
EN

Stack Overflow用户

发布于 2015-11-24 07:31:41

这将是while循环的模板。如果你想读一整行,那就别费心在读取行中放一个变量,并且停止无用的单词拆分。

while read -r; do line=$REPLY ... done <<<"$OUTPUT"

请参阅Bash-Hackers

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33882343

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档