Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have several lists and want to run some commands over them. As lists are long I want to run those commands parallel to each other, hence using nohup.
For every item I tried to echo a loop that contains a nohup command, but it doesn't work - cat another_list_of_names reads to stdout, but not into ./tools. First cat in for a in $(cat list_of_names) sends list to loop, but echo'ed for b in $(cat another_list_of_names) sends it to stdout.
How can I set those nohup commands running in parallel (is it possible to run nohup with echo)?

for a in $(cat list_of_names)
      do              
          ID=`echo $a`
          mkdir ${ID}
          echo " 
             nohup sh -c '
             for b in $(cat another_list_of_names)
               do 
                  ./tools $b $a >> ${ID}/output
               done' &
           "

      done
share|improve this question
1  
${ID} is a directory and you are sending stdout to that. Don't you need to send it to a file? Also, in the third line, you can simply say ID=$a. Or better still, use ID in loop header. –  unxnut May 28 '13 at 12:01
    
What is "it doesn't work" supposed to mean? –  Hauke Laging May 28 '13 at 12:03
    
It doesn't work as cat another_list_of_names reads list into stdout, but not into ./tools. –  Pgibas May 28 '13 at 12:26
    
I think you have problems too due to how you're quoting variables. Things aren't going to get expanded correctly with the single quotes. –  slm May 28 '13 at 12:34
    
@slm I'm not quite sure what the OP intends to do, but I guess that the problems are due to the double quotes. The single quoted variables should not be expanded, but since the single quotes themselves are double quoted, that fails. –  Uwe May 28 '13 at 12:37

4 Answers 4

up vote 4 down vote accepted

You seem to be confused about what echo does. You cannot run any commands using echo, not specifically nohup. echo simply displays text, it does not execute it.

Now, if I understand what you want to do correctly, all you need is this:

#!/usr/bin/env bash
## As others have said, this is a better loop for your purposes
## and it avoids both useless uses of cat.
while read a
do         
    ## you don't need to copy the variable; you need the
    ## quotes to cope with names with spaces.    
    mkdir "$a"
    while read b
    do
      nohup ./tools $b $a >> "$a"/output &
    done < another_list_of_names
done < list_of_names
share|improve this answer
    
Will this run $b one by one or all at the same time? Because what I tried to do is to run all $b at the same time, that's why I tried using nohup. –  Pgibas May 28 '13 at 14:10
    
@Poe they will run in parallel, that's what the & (run in background) at the end of the nohup does. –  terdon May 28 '13 at 14:11

I made some improvements to your code:

# This sort of loop is generally preferable to the one you had.
# This will handle spaces correctly.
while read a
do
   # There's no need for the extra 'echo'
   ID="$a"
   # Quote variables that may contain spaces
   mkdir "$ID"
   # This is a matter of taste, but I generally find heredocs to be more
   #  readable than long echo commands
   cat <<EOF
   nohup sh -c '
   while read b
   do
      # Quotation marks
      ./tools \$b $a >> "${ID}/output"
   done < another_list_of_names' &
EOF
done < list_of_names
share|improve this answer
1  
This looks like a reasonable answer. Something along the lines I had thought about as well. I still say the question is confusing. –  unxnut May 28 '13 at 13:12

I'm not quite sure that I understand what you want. Just guessing: does one of the following code fragments do the intended thing?

for a in $(cat list_of_names)
do
    ID=`echo $a`
    mkdir ${ID}
    echo '
        nohup sh -c '\''
        for b in $(cat another_list_of_names)
        do
            ./tools $b $a >> ${ID}/output
        done'\'' &
    '
done

or

for a in $(cat list_of_names)
do
    ID=`echo $a`
    mkdir ${ID}
    echo "
        nohup sh -c '
        for b in $(cat another_list_of_names)
        do
            ./tools \$b $a >> ${ID}/output
        done' &
    "
done
share|improve this answer
    
The first code fragment won't substitute the variables ID and a within the nohup command. –  paraxor May 28 '13 at 13:03
    
That is because of the use of single quotes. Single quotes prevent the variables from being substituted. –  unxnut May 28 '13 at 13:09
    
@EvanTeitelman Sure. The two fragments do different things; I just didn't know which of them the OP wanted. –  Uwe May 28 '13 at 14:06

Are you trying to echo this out to see the what the final commands going to look like? or are you trying to actually trying to run the nohup command with that echo?

I'd suggest adding the line to the top of your script, set -x so that you can see what each line is doing rather than try and grok it by just looking at it.

You can turn set -x on off as needed in scripts too:

set -x

... code to debug ...

set +x
share|improve this answer
    
I edited my question with the problem I have. –  Pgibas May 28 '13 at 12:26

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.