bash command line - how to convert multiple line into a single line for sh -c
Solution 1
The way I see it is you have two options:
- Put that in a script-file and run THAT
- Replace every newline in the bigger code window above with a semicolon
I'd go with 1, personally.
Solution 2
There's no problem having newline characters in the argument to sh -c
. {1..10}
is zsh
syntax though (now supported by a few other shells), not sh
. If your sh
outputs anything but {1..20}
upon echo {1..20}
, then it's a POSIX conformance violation and you should be ready for it to be fixed in newer versions. You can use:
zsh -c '
for i in {1..10}
do
for j in {1..10}
do
echo "test inner"
done
echo "test outer"
done'
Or
sh -c '
i=1; while [ "$i" -le 10 ]
do
j=1; while [ "$j" -le 10 ]
do
echo "test inner"
j=$((j + 1))
done
echo "test outer"
i=$((i + 1))
done'
But it feels silly to run 100 echo
commands for that while you could do it with just one command:
awk 'BEGIN{
for (i=1; i<=10; i++) {
for (j=1; j<=10; j++)
print "test inner"
print "test outer"
}}'
Which you can put on a single line if you want with:
awk 'BEGIN{for(i=1;i<=10;i++){for(j=1;j<=10;j++)print"test inner";print"test outer"}}'
Solution 3
To convert this to a single line. I added a few ;
in the correct locations:
for i in {1..10}; do for j in {1..10}; do echo "test inner ${j}"; done; echo "test outer ${i}"; done;
The above line will work with bash
but to run this with sh -c
you need to expand the {1..10}
(as far as I know) because sh
does not support that range syntax. In that case the following line works for me:
sh -c 'for i in 1 2 3 4 5 6 7 8 9 10; do for j in 1 2 3 4 5 6 7 8 9 10; do echo "test inner ${j}"; done; echo "test outer ${i}"; done;'
Note: I added ${j}
and ${i}
to confirm.
Related videos on Youtube
Weishi Z
Updated on September 18, 2022Comments
-
Weishi Z over 1 year
In OSX command line, I have some logic as following.
for i in {1..10} do for j in {1..10} do echo "test inner" done; echo "test outer" done
It runs fine. But I want to run it from
nohup
. So I need to combine above into a single line to fit intonohup sh -c "{a single line}"
However, the following line gives error. It simply skipped all the line break from above.
sh -c 'for i in {1..10} do for j in {1..10} do echo "test inner" done; echo "test outer" done'
Error:
sh: -c: line 0: syntax error near unexpected token `echo' sh: -c: line 0: `for i in {1..10} do for j in {1..10} do echo "test inner" done; echo "test outer" done'
Edit:
I did not want to run it as a file as the command has slightly protected credentials. The easiest way I can think of is to run it as a command so it doesn't leave a file on the shared VM. I don't know how well this protects the credentials or there is a better way. More suggestions/ideas are welcome.
Edit:
Using bash and single quote makes it work. (based on Tigger's answer)
bash -c 'for i in {1..10}; do for j in {1..10}; do echo "test inner"; done; echo "test outer"; done;'
-
heemayl over 6 yearsWhy don't you put the stuffs in script and run that script with
nohup
(or preferablydisown
)? -
kmacdonald over 6 yearsIs this about
bash
orsh
? The question content only mentionssh
, but this has been taggedbash
and the title mentionsbash
.
-
-
Weishi Z over 6 yearsThanks for pointing out
There's no problem having newline characters in the argument
!