2

The main function execSteps executes emerge --pretend $package one by one, and these package's names(only names, no version information) are stored in a text file stepFile. Some of packages may have extra need for configuring package.use, package.license, this kind of extra information will be shown up after executed emerge --pretend $package. The second while loop in main function and function acceptPKGTypeItems are intended to deal with this kind of extra information.

When emerging one particular package, it may depend on a couple of more packages. For example, emerge --pretend ceph, I need to emerge more than 10 packages before ceph gets emerged. Along with Gentoo/Linux updated, new version of package may be applied. So text file stepFile only contained with package names which I need, and parsing the result of emerge --pretend $package, I'm able to get updated package emerged.

At case 0), this while loop is intended to parse the result of emerge --pretend $line(which is from stepFile), for example emerge --pretend ceph and get its dependant packages with current version, for example dev-libs/boost-1.57.0, pass it as an argument to function emgRecursion because dependant package dev-libs/boost-1.57.0 of package ceph may have its own dependant packages which are dev-libs/boost-build-1.57.0 and dev-libs/boost-1.57.0.

My problem is I get an error while : command not found in function emgRecursion when I enter 0 at case 0). Is it another different shell thing? I've added a pair parenthesis between the second while loop in main function which helped get readin answer from user for choosing package.use, package.license, or package.keywords. And I've tried to add another pair of parenthesis between the third while loop, the same problem. I've tested emgRecursion and acceptPKGTypeItems separately, both of them work fine and correctly.

Any ideas? Thank you very much.

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

Nothing will stop while loop in main function, output:

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
Tao Wang
  • 186
  • 1
  • 18
  • 1
    The empty body of the while loop is probably giving you a problem. Try putting something (like `true` or `:`) in there. – Etan Reisner Nov 23 '15 at 23:18
  • Well, I just cut it off, there is something there when I run it. Thank you Etan, please help me! I've almost done what I expected. Just this problem so far. – Tao Wang Nov 23 '15 at 23:22
  • Add `set -x` to the script and show the output around where this breaks. – Etan Reisner Nov 23 '15 at 23:34
  • I'm sorry, what? You added `set -x` and what happened? You don't have the problem anymore? You have some other problem instead? – Etan Reisner Nov 23 '15 at 23:42
  • Problem is still the same, nothing changed. – Tao Wang Nov 23 '15 at 23:44
  • You appear to have missed the **and show the output around where this breaks** part of my `set -x` comment. – Etan Reisner Nov 23 '15 at 23:46
  • Run your code through [ShellCheck](http://www.shellcheck.net). – user3439894 Nov 24 '15 at 00:08
  • The error appears to occur in the call to `emgRecursion`, so the problem likely exists in the code that you omitted from the question. – chepner Nov 24 '15 at 03:55
  • BTW, see http://stackoverflow.com/help/mcve for guidelines on how to build and ask better questions. If other folks could reproduce your problem, and it included absolutely no content other than the minimum to generate that problem, this would have been handled much more quickly. – Charles Duffy Nov 24 '15 at 17:26
  • ...it looks to me, by the way, like your script contains nonprintable characters that your `/bin/sh` doesn't parse as whitespace but your `/bin/bash` does. `while` is part of POSIX sh, so even `/bin/sh` will parse it as syntax; but if you have tabs that aren't the standard `$'\t'` character, then all bets are off in terms of whether any given shell will correctly parse code that contains them. – Charles Duffy Nov 24 '15 at 17:27

2 Answers2

0

Problem solved by copying functions other than emgRecursion to another file while I created for testing emgRecursion.

I realized that the difference between these two files(recursion for testing emgRecursion, step for test whole function) is recursion was originally created with #!/bin/bash, and step was originally a plain shell text file without any first line symbol and then I added #!/bin/bash to it. I thought there was no big difference between bash text file and shell text file in terms of syntax. In fact, THEY ARE TOTALLY DIFFERENT. If you mixed them up like my case, it's a WASTE of time.

Tao Wang
  • 186
  • 1
  • 18
-1

This would be a template for your while loop. If you want to read a whole line then don't bother with putting a variable in the read line and stop useless Word splitting occurring.

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

See Bash-Hackers

Gerrit
  • 861
  • 6
  • 11
  • I'd appreciate your participation, my question is obviously not about how to read line from a variable, I said I've tested sub-function separately, they all worked fine. – Tao Wang Nov 23 '15 at 23:36