I made a bash script. It reads a file contains a list of commands and runs each of them.
A list of commands is like below.
ENV_NUMBER=1 command1 ENV_NUMBER=2 command2 ENV_NUMBER=3 command3
Each line has a environment variable before command to set same name but different value to commands.
A script is like below.
while read line do if [ -n $line ] ; then # run command in background $line & fi done < comandlist.txt
I expect:
- run command1 with ENV_NUMBER=1
- run command2 with ENV_NUMBER=2
- run command3 with ENV_NUMBER=3
But, I ran script then I got error:
ENV_NUMBER=1: command not found
How do I fix it?
Advertisement
Answer
Your logic looks good from inside the command file…
See https://www.gnu.org/software/bash/manual/bash.html#Simple-Command-Expansion
The problem is that you are loading the variable assignment into a variable, rendering it as data rather than a command, then trying to context-hack it back.
ENV_NUMBER=1 command
is not the same as
"ENV_NUMBER=1" "command"
which is what you are effectively doing.
Try this instead.
sed -Ei 's/$/&/' comandlist.txt # make sure there are no blank lines first!
then either
chmod x comandlist.txt ./comandlist.txt
or
source comandlist.txt
This makes comandlist.txt
the script, complete with the ampersands, which it otherwise kind of already was. Your program reads it in as data and then tries to convert it back to script a line at a time. Don’t do that.
c.f. https://mywiki.wooledge.org/BashFAQ/050
Original answer – for reference
Are you sure you are using bash?
Do you have something like #!/bin/bash
as the first line of your script?
Here’s my simple example script:
$: cat y #! /bin/bash echo "x=[$x]" # using whatever is available, not setting in the script
Running it with no x
value:
$: unset x; ./y # nothing to show, x has no value x=[]
Running it with an x
set:
$ x=foo; ./y # NOT exported to the subshell! Can't see it. x=[]
Explicitly setting it temporarily in the command itself:
$: x=foo ./y # this creates x in this subshell, goes away when it ends x=[foo]
Running again without setting to show it’s temporary…
$ ./y # didn't keep from last run x=[]
Explicitly exporting in the parent environment:
$: export x=bar; ./y # reads the exported value from the parent x=[bar]
Manually overriding the exported value by supplying a temporary value from the command line:
$: x=foo ./y # overrides exported value of "bar" in the subshell *only* x=[foo]
Running again with no special edit, using the still-exported value:
$: ./y # x still exported as "bar" x=[bar]
So obviously what you are doing works fine in bash
.
As I mentioned above, maybe you are not using bash
.
Make sure you have a shebang. #!
have to be the very first two characters in the file for it to work – no spaces above or before, no comments, nothing.
Let us know if that doesn’t help.