2

The following sequence of commands

ch=`echo "b_d" | sed 's/_/\\\\\\\\_/'`
echo $ch

when executed in a terminal or via source give an output

b\\_d

When ran as a scipt

sh script.sh

where the script contents are:

#!/bin/bash                                                                                                                                   
ch=`echo "b_d" | sed 's/_/\\\\\\\\_/'`
echo $ch

the output is

b\_d

The output from the terminal is the preferred one. What is the solution for using the shell script? Also accepted as answers are ideas how to modify

ch=`echo "b_d" | sed 's/_/\\\\\\\\_/'`

for sh.

I use the bash shell:

echo $0
bash
  • 1
    What bash version do you use? I cannot repeat your problem. – schily Aug 25 '18 at 9:18
  • 3
    sh is not bash. Also, if you run $SHELL foo.sh the shebang line is ignored. Please show us exactly what you are running. – l0b0 Aug 25 '18 at 9:25
  • @I0b0, I updated the question – Viesturs Aug 25 '18 at 11:32
2

sh differs from bash and behaves different.

I guess that sh is really dash.

BTW: there is different behavior with this command if you check different shells.

bosh, dash, mksh, zsh as well as ksh on Solaris print one backslash

bash and ksh on Linux print two backslashes.

From looking at the $shell -x output, I believe that one backslash is the correct output.

I have no idea why ksh behaves this way on Linux. It could be that it tries to mimic bash behavior.

For bash the behavior can be explained: bash has a non-POSIX echo that does not interpret backshlashes as required by POSIX.

POSIX permits the behavior of bash only on small embedded systems and POSIX otherwise requires the so called XSI extensions to be implemented. With echo, this requires to fully follow the behavior of echo as impleented in 1982 by AT&T for SYSv.

An important note:

If you have a script that starts with

#!/bin/bash

and that is executable (x bit set bychmod), and if you call

sh myscript

this script is still run by /bin/sh which is typically dash on Linux. So be careful on how you run your code.

There is a way to avoid your problem. Change your script to use:

ch=`echo "b_d" | sed 's/_/\\\\\\\\_/'`
printf '%s\n' $ch

This way, you avoid the problems with echo that have been introduced in 1989 with bash. printf does still not solve all problems since there are many buggy implementations, but the usual problems that arise from backslashes in the arguments are not affected by printf.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.