1

I have some command lines stored in a text file, and I separated them into different groups by using distinguished row symbol, say #step1 for group one, #step2 for group two,etc. My question is how I'm able to extract each group and execute each command line by using #step* as an input argument.

steps text file:

#step1
command line 1
command line 2
command line 3
...
#step2
command line 4
command line 5
command line 6
...

How to create a function somewhere in my code context, which can do something like:

execSteps "#step1"

or is there another way to organize my steps text file?

Any ideas?

Thank you very much!

Tao Wang
  • 186
  • 1
  • 18
  • 1
    This isn't an array at all unless you want to store all the steps in memory rather than parsing through the file every time. Which... would actually be reasonable, but it isn't part of the specification whether to do that or not. – Charles Duffy Nov 11 '15 at 00:04
  • The reason why I'd like to do this is each time when I install new version of Gentoo Linux to my computer, package names maintain the same, but the USE flags always change. I decided to store package names which I want to install to a text file and separated them into different groups so that I'm able to accept USE flags as input parameters and don't have to worry about the procedure and type 'emerge packagename' again and again. Even if I've stored the whole procedure to an executable script file, it's boring to update USE flags when new version Gentoo stage and portage are available. – Tao Wang Nov 12 '15 at 16:34
  • Rest of emerging packages are some command lines like 'cp', 'mkdir', 'rc-update', and they also had to be mixed among those emerging steps, which means they had been separated into different steps stored in a text file as emerging steps did. This thread is mainly about how to deal with these grouped command lines. – Tao Wang Nov 12 '15 at 17:26
  • Hmm. If you want to execute those groups inside the current shell, you might want to `eval "$(getSteps "$@")"` rather than using `getSteps "$@" | sh -`, which executes the steps in a separate child shell. – Charles Duffy Nov 12 '15 at 18:01
  • Would you please suggest what would happen if these steps are not in the same shell? I used `chroot` to run `emerge package` remotely. Does it matter? – Tao Wang Nov 13 '15 at 18:33
  • The details matter -- I can't give you an answer from only the one line above. – Charles Duffy Nov 13 '15 at 18:47

2 Answers2

1

One approach:

getSteps() {
  local running=0
  while read -r line; do
    if (( running )); then
      if [[ $line = "#"* ]]; then
        return
      else
        printf '%s\n' "$line"
      fi
    else
      [[ $line = "#"$1 ]] && running=1
    fi
  done <stepFile
}

execSteps() {
  getSteps "$@" | sh -
}

Then, you can print the code for a step by running getSteps step1, or execute that code with execSteps step1.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • Thank you very much, Charles! It worked for me very well. – Tao Wang Nov 12 '15 at 17:47
  • Hi, Charles, if I'd like to take one step further, say in the function getSteps() at line `printf '%s\n' "$line"`, separate this step into two substeps, substep1: execute `emerge --pretend $line(packagename)` , collect USE flags manually, and set make.conf, substep2: execute `emerge $line(packagename)`. My further question is how to execute emerge inside this while loop? Don't worry about other stuff. Thank you again. – Tao Wang Nov 13 '15 at 17:40
  • The comment above is too dense to be unambiguously understood. I'd suggest asking a new question focused specifically on the place you're having trouble, with the parts you do understand factored out. – Charles Duffy Nov 13 '15 at 18:51
  • @TaoWang, please add your own answer with your extended version of the code -- the edit you suggested was somewhat too expansive to include here, but I'd be glad to upvote it as a separate answer. (Yes, I treat all comments as tags; that was intentional, because the question wasn't clear enough about what did and did not constitute a tag). – Charles Duffy Nov 18 '15 at 22:55
  • @MikeWise, please consider being more cautious about which edit suggestions you approve. The change you approved suggested code with a great deal of functionality which had nothing to do with the actual question, and other adjustments it made were related to unstated (as opposed to explicit) requirements. – Charles Duffy Nov 18 '15 at 22:59
1

It sounds like you just want to define a shell "module". Save it as mymodule:

step1 () {
    command line 1
    command line 2
    command line 3
}

step2 () {
    command line 4
    command line 5
    command line 6
}

To use it, simply source it from your script, and call the desired function

. mymodule
# Run step 1
step1

# Run step 2
chepner
  • 497,756
  • 71
  • 530
  • 681