user2547609
user2547609

Reputation: 3

Print shell command lines in C with printf()

I am trying to build a shell program with a c program. Basically I need a text file with the same shell commands repeated over and over but with one part changed. I tried to build a C program to count from 1 to 750 and print out the paragraph with that one digit changed but it is trying to read the shell commands and giving me errors. How do I have it ignore the shell commands and just print what's in the printf?

Here is the program:

#include <stdio.h>

int main ()
{
    int x;
    for(x=1;x<751;x++){
        printf("#!/bin/sh");
        printf("NRNHOME="/Applications/NEURON-7.3/nrn"");
        printf("\NEURONHOME="${NRNHOME}/share/nrn"");
        printf("CPU=i386");
        printf("NRNBIN="${NRNHOME}/i386/bin/"");
        printf("PATH="${NRNHOME}/i386/bin:${PATH}"");
        printf("export NRNHOME");
        printf("export NEURONHOME");
        printf("export NRNBIN");
        printf("export PATH");
        printf("export CPU");
        printf("nrncarbon=yes");
        printf("export nrncarbon");
        printf("cd "\${NRNHOME}/i386/bin"");
        printf("./nrngui.sh "/Applications/NSD2013/s%d.hoc"\n\n",x);
    }
}

It's telling me all the directories are undeclared and it expects a ) before $? All I want is to have it print out the commands changing the .hoc file in the very last line beginning with s1.hoc and ending with s750.hoc.

Thanks in advance for your advice.

Upvotes: 0

Views: 1408

Answers (3)

fvu
fvu

Reputation: 32953

Aside from the fact that your program will generate a relatively useless long output list of 750 times almost the same script that you will probably have to chop up in 750 separate scriptfiles, there are a number of concrete problems that cause it to malfunction:

    printf("#!/bin/sh");
  1. because this statement is inside the loop, it will be
  2. printf doesn't add newlines by itself, add \n if you want the next printf to start on a new line

    printf("\NEURONHOME="${NRNHOME}/share/nrn"");
    
  3. Pretty sure that \N at the start is unintentional

  4. double quotes inside the string should be escaped, eg \"

    printf("cd "\${NRNHOME}/i386/bin"");
    

Not sure why you seem to escape the $ here...

    printf("./nrngui.sh "/Applications/NSD2013/s%d.hoc"\n\n",x);
}

Anyways, it's pretty easy to do this in pure shellscript, and send the output to 750 different script files in 1 blow:

for i in {1..750}  ; do
cat << EOT > the_output_script$i.sh
#!/bin/sh
NRNHOME="/Applications/NEURON-7.3/nrn"
...      
# If you want bash to ignore variables that should be evaluated later on
# you just need to escape the dollarsign
NRNBIN="\${NRNHOME}/i386/bin/"
./nrngui.sh "/Applications/NSD2013/s$i.hoc
EOT
# we're after the end of the heredoc, so here we can add other stuff that
# needs to be done in the loop, like changing the file's access:
chown ug+x the_output_script$i.sh
done

which will produce 750 files named the_output_script1.sh to the_output_script750.sh which is what I think you're really looking for. Btw, the core trick used in this script is called a heredoc or here document

Upvotes: 3

George Mitchell
George Mitchell

Reputation: 1168

Ok, to maintain your original intent (for educational purposes only):

#include <stdio.h>

int main ()
{
    int x;

    for(x=1;x<751;x++) {
        printf("#!/bin/sh\n");
        printf("NRNHOME=\"/Applications/NEURON-7.3/nrn\"\n");
        printf("NEURONHOME=\"${NRNHOME}/share/nrn\"\n");
        printf("CPU=i386");
        printf("NRNBIN=\"${NRNHOME}/i386/bin/\"\n");
        printf("PATH=\"${NRNHOME}/i386/bin:${PATH}\"\n");
        printf("export NRNHOME");
        printf("export NEURONHOME");
        printf("export NRNBIN");
        printf("export PATH");
        printf("export CPU");
        printf("nrncarbon=yes");
        printf("export nrncarbon");
        printf("cd \"${NRNHOME}/i386/bin\"\n");
        printf("./nrngui.sh \"/Applications/NSD2013/s%d.hoc\"\n\n",x);
    }
}

Now, another way to do it would be (my_script.sh):

#!/bin/sh
NRNHOME=/Applications/NEURON-7.3/nrn
NEURONHOME=${NRNHOME}/share/nrn
CPU=i386
NRNBIN=${NRNHOME}/i386/bin/
PATH=${NRNHOME}/i386/bin:${PATH}
export NRNHOME
export NEURONHOME
export NRNBIN
export PATH
export CPU
nrncarbon=yes
export nrncarbon
cd ${NRNHOME}/i386/bin
./nrnqui.sh /Applications/NSD2013/s*.hoc // the lazy way

OR: my_script.sh: // with a for loop

#!/bin/sh
NRNHOME=/Applications/NEURON-7.3/nrn
NEURONHOME=${NRNHOME}/share/nrn
CPU=i386
NRNBIN=${NRNHOME}/i386/bin/
PATH=${NRNHOME}/i386/bin:${PATH}
export NRNHOME
export NEURONHOME
export NRNBIN
export PATH
export CPU
nrncarbon=yes
export nrncarbon
cd ${NRNHOME}/i386/bin
for i in {1..750}
do
    ./nrnqui.sh /Applications/NSD2013/s{$i}.hoc
done

Upvotes: 1

VoidPointer
VoidPointer

Reputation: 3097

This could do it,

#include <stdio.h>

int main ()
{
    int x;
    for(x=1;x<751;x++){
        printf("#!/bin/sh\n");
        printf("NRNHOME=\"/Applications/NEURON-7.3/nrn\"\n");
        printf("NEURONHOME=\"${NRNHOME}/share/nrn\"\n");
        printf("CPU=i386\n");
        printf("NRNBIN=\"${NRNHOME}/i386/bin/\"\n");
        printf("PATH=\"${NRNHOME}/i386/bin:${PATH}\"\n");
        printf("export NRNHOME\n");
        printf("export NEURONHOME\n");
        printf("export NRNBIN\n");
        printf("export PATH\n");
        printf("export CPU\n");
        printf("nrncarbon=yes\n");
        printf("export nrncarbon\n");
        printf("cd \"${NRNHOME}/i386/bin\"\n");
        printf("./nrngui.sh \"/Applications/NSD2013/s%d.hoc\"\n\n",x);
    }
}

I strongly recommend you to learn printf here. Refer sources given here to know about language

Upvotes: 0

Related Questions