Reputation: 621
docker run --rm \
/bin/bash -c "\
su - hello && \
echo \"Pre\" && \
python ${M} ${F} ${D} ${B} && \
echo \"Post\" && \
CHECK_VALUE=`$(cat B)` && \
echo ${CHECK_VALUE} && \
"
My problem is ${B} is a file produced by python code. But whenever I run this I get the following log:
cat: /home/hello/D/W/H/b.txt: No such file or directory
Pre
Post
And also in empty line This clearly means my python code is unfinished and the next line is run. Please help How do I read the file into a variable only after its written? And why such ambiguous behaviour?
Upvotes: 1
Views: 62
Reputation: 189820
You have multiple errors in this part:
`$(cat B)`
You are mixing two command substitutions. $(cat B)
is synonymous to `cat B`
so what you have here is actually equivalent to $($(cat B))
. In other words, take the contents of B and use it as a command, then substitute that command's output.
Moreover, because you are using double quotes around the command, this construct is evaluated when the command is parsed, not when it is executed. You can prevent this by backslash-escaping the dollar sign.
Additionally, you need to escape ${CHECK_VALUE}
in order to prevent the shell from interpolating it when evaluating the string, just like the command substitution. I would also recommend quoting the value, unless you expect it to contain a single token (and perhaps even then, just for your own sanity).
Finally, you have a dangling &&
with nothing after it. This is a syntax error.
Here is your script with my fixes:
docker run --rm \
/bin/bash -c "\
su - hello && \
echo \"Pre\" && \
python ${M} ${F} ${D} ${B} && \
echo \"Post\" && \
CHECK_VALUE=\"\$(cat B)\" && \
echo \"\${CHECK_VALUE}\""
I also added quotes around the cat
in case its output contains shell metacharacters.
... though capturing a variable just so you can echo
it is an antipattern; probably you simply want to cat ${B}
as the final command.
If you expect su - hello
to cause the subsequent commands to run as hello
, that's also wrong (though a common newbie mistake). su
spawns a new shell and the following command will execute when that shell is terminated (not inside it). You probably mean su -c "python $M $F $D $B" hello && cat "$B"
plain and simple. Wrapping it in the docker
command line, try
docker run --rm \
/bin/bash -c "su -c 'python $M $F $D $B' hello && cat $B"
where the single quotes do not prevent variable interpolation, because inside the double quotes, they are not actually quoting anything (compare echo "don't"
where obviously the apostrophe would be problematic if in fact it had quoting semantics).
Upvotes: 5