Issue
I have written a script that takes a txt file from a folder and I want to insert a blank line at the end of the file, and then write to it. But I have a problem, because the console returns: sed: -e expression #1, char 4: unknown command: `'.
This is code:
adb shell "sudo cp /boot/uEnv.txt /home/rock/"
adb shell "sudo sed -i '$s/$/\n/' /home/rock/uEnv.txt"
adb shell "sudo sed -i '$i extraargs=rtl8723ds.rtw_initmac=\"MACAUXTXT\"' /home/rock/uEnv.txt"
adb shell "sudo sed -i "s/MACAUXTXT/$(cat /sys/class/net/wlan0/address | sed 's/.\{9\}//' | sed 's/^/00:e0:4c:/' )/" /home/rock/uEnv.txt"
adb shell "sudo cp /home/rock/uEnv.txt /boot/"
adb shell "sudo cp /home/rock/Service/20-rock.conf /usr/lib/NetworkManager/conf.d/"
adb shell "sudo rm /home/rock/Service/rockpi-backup.sh"
adb shell "sudo rm /home/rock/Service/20-rock.conf"
adb shell "sudo rm /home/rock/uEnv.txt"
This is problem: enter image description here
Solution
The issue is with nested quoting:
adb shell "sudo sed -i '$s/$/\n/' /home/rock/uEnv.txt"
The shell that runs the adb
command processes all of its arguments, including the sudo ...
part in double quotes. Since double quotes allow variable expansion by the shell, $s
is expanded before sed
or even sudo
is executed.
Depending on what you have stored in the variable named s
, it is substituted and finally processed by sed
. If you don't have an s
variable, an empty string is substituted and $s
disappears.
You can see for yourself if you substitute echo
for adb
:
echo shell "sudo sed -i '$s/$/\n/' /home/rock/uEnv.txt"
shell sudo sed -i '/$/\n/' /home/rock/uEnv.txt
Now sed
's middle argument is /$/\n/
instead of $s/$/\n/
. /$/
is interpreted as a regular expression filter to decide which lines to operate on, and \n/
as the command and its arguments. Since \
is not a valid command, you get the error described.
There are several ways to go about this.
I can't name a good solution off the top of my head, but one solution is to escape the dollar sign in the top-most shell so it is passed untouched to the subshell:
adb shell "sudo sed -i '\$s/\$/\n/' /home/rock/uEnv.txt"
I escaped the second dollar symbol for good measure as well, although in your case, it has no effect. It is not substituted, because /
is not a legal variable name. However, if you later decided to e.g. change the sed
command's separator to #
to, for instance, deal with file names in the pattern or substitution string, the second dollar symbol would already become a problem, because #
is the name of the argument-count shell variable.
Answered By - Larry Answer Checked By - Pedro (WPSolving Volunteer)