1
#!/bin/sh
INF_PROC=`ps -l`
for (( i=1; i<5; i++ ))
do
    id$i=$(echo $INF_PROC | cut -d ' ' -f $i)
    echo $id$i
done

Im learning bash and trying to use a for similar to this but it gives me an error. "Command not found" Why is that?

Bill Hileman
  • 2,798
  • 2
  • 17
  • 24
VicRP9
  • 11
  • 3
  • 1
    if you're learning bash, be sure to use `#!/bin/bash` at the top of your scripts. Using `#!/bin/sh` imposes significant restrictions on what features you can use. AND use the `{}` tool from the Format Menu on mouse-selected text to format correctly as `code/data/errMsgs`. Good luck. – shellter Dec 15 '19 at 18:47
  • 5
    The problem is `id$i=...`. Someone link this as a duplicate. – Socowi Dec 15 '19 at 18:47
  • 2
    AND check you code before posting at https://shellcheck.net . Good luck. – shellter Dec 15 '19 at 18:48
  • 1
    @shellter Thanks for the tips, the /sh may be because im using xcode on mac. I didn't know how to format the menu, thanks again – VicRP9 Dec 15 '19 at 18:50
  • 1
    I agree with @Socowi . Read this post to understand your problem https://stackoverflow.com/questions/18018808/how-to-create-a-dynamic-variable-and-assign-value-to-it?noredirect=1&lq=1 . Good luck. – shellter Dec 15 '19 at 19:36
  • 3
    It looks like an array would be a much cleaner solution than a dynamic variable name. Just use `id[i]=...` and `echo "${id[i]}"`. (I'm sure there's already a q/a that covers this, but I can't find it at the moment). – Gordon Davisson Dec 15 '19 at 21:29
  • 2
    I've added a couple of duplicates with answers that cover using arrays for situations like this. – Gordon Davisson Dec 15 '19 at 22:43
  • @GordonDavisson that's exactly what i needed, thanks – VicRP9 Dec 16 '19 at 17:04
  • I've found it works without indent the text, so command must be starting same as 'do' – Pawel Cioch Jan 02 '23 at 06:17

1 Answers1

-2

The shebang #!/bin/sh is the deciding factor on which shell executes your script.

Since the script is using bash-specific features, namely (( i=1; i<5; i++ )), the shebang should be #!/bin/bash.

Alternatively you can rewrite the script in such a way that it only uses elements that can be interpreted by all POSIX-compliant shells, such as sh.

You can do this by writing your loop like so:

#!/bin/sh
INF_PROC=`ps -l`
for i in $(seq 5)
do
    id$i=$(echo $INF_PROC | cut -d ' ' -f $i)
    echo $id$i
done
gutjuri
  • 57
  • 6
  • 1
    it gives me the same error: pruebainfocomando.sh: line 7: id1=UID: command not found 1 pruebainfocomando.sh: line 7: id2=PID: command not found 2 pruebainfocomando.sh: line 7: id3=PPID: command not found 3 pruebainfocomando.sh: line 7: id4=F: command not found 4 pruebainfocomando.sh: line 7: id5=CPU: command not found 5 – VicRP9 Dec 15 '19 at 18:56
  • 1
    try `echo $INF_PROC | cut -d ' ' -f $i | read id$i` instead of `id$i=$(echo $INF_PROC | cut -d ' ' -f $i)`. – gutjuri Dec 15 '19 at 19:02
  • 1
    Now it returns 1 2 3 4 5, but i need the words UID, PID, PPID,CPU – VicRP9 Dec 15 '19 at 19:05
  • 1
    `Read` in a pipeline will not work because the commands in pipelines run in a subshell. Use `declare variable=value` with subshells `$()` instead. But even better: Don't answer this question which was answered multiple times. Search for duplicates and mark it as a duplicate. – Socowi Dec 15 '19 at 19:07
  • @socowi How would you edit the code? I don't understand what do you mean – VicRP9 Dec 15 '19 at 19:16
  • 3
    @juri_d You've completely ignored the real problem, which is the assignment to `id$i`. – chepner Dec 15 '19 at 19:31