Issue handling single quoted argument in shell script.

Below is my script that works fine and prints the desired output:

#!/bin/ksh
echo "$1" |
  while IFS= read -r dirpath
do
  echo "DIRR_PATH:$dirpath"
  install_dir=$install_dir" "$dirpath
done
echo "Desired Output:$install_dir"

Output:

./loopissue.sh "/tmp/scripts\\n/tmp/mrt\\n/tmp/exe"
DIRR_PATH:/tmp/scripts
DIRR_PATH:/tmp/mrt
DIRR_PATH:/tmp/exe
Desired Output:/tmp/scripts /tmp/mrt /tmp/exe

The problem is i'm not getting a clean way to seperate the arguments with a single white space as seen in the "desired output:" above when the parameters are passed in single qoutes like below:

./loopissue.sh '/tmp/scripts\\n/tmp/mrt\\n/tmp/exe'

I'm on Aix6.1 and ksh shell.

Can you please suggest how can I get similar output when the argument is passed in single quotes ?

I tried removing the single quotes using the below two approaches but that did not help.

sed "s/'//g"
tr -d"'"

In Summary: All \\n should be replaced by single white space and single quotes should be removed from the argument and stored in a variable.

In single quotes you must not \escape the \escape:

./loopissue.sh '/tmp/scripts\n/tmp/mrt\n/tmp/exe'

The shell removes the 'single quotes' and the "double quotes" before it invokes the loopissue.sh. The quotes are only the hint to pass it as one string - to $1 in the loopissue.sh.
Also the following works (and is even better portable, because the \n must be interpreted by the echo command):

./loopissue.sh '/tmp/scripts
/tmp/mrt
/tmp/exe'

Is there a reason to squeeze all arguments into one $1 ?
Maybe you can simply use

./loopissue.sh /tmp/scripts /tmp/mrt /tmp/exe

This maps to $1 $2 $3 in the loopissue.sh
And it's simple to print them in different formats:

#!/bin/ksh
for dirpath
do
  echo "DIRR_PATH:$dirpath"
done
echo "Desired Output:$@"

Note that for dirpath is short for for dirpath in "$@" . In other words, a for loop defaults to loop thru all arguments.

The arguments passed to the script come from the database in the format I shared and cannot be changed hence the proposed solution would not work.

Is there a way to replace all \\n to single whitespace as requested in the original post?

Hi,

Is this what you are expecting;

#!/bin/ksh
VAR1=`echo -e "${1}" | sed -e "s/'//g"`
echo -e "${VAR1}" |
  while IFS=' '
read -r dirpath
do
  echo "DIRR_PATH:$dirpath"
  install_dir=$install_dir" "$dirpath
done
echo "Desired Output:$install_dir"

Where it is run as;

./tester.sh '/tmp/scripts\\n/tmp/mrt\\n/tmp/exe'

With this as the Output;

DIRR_PATH:/tmp/scripts
DIRR_PATH:/tmp/mrt
DIRR_PATH:/tmp/exe
Desired Output: /tmp/scripts /tmp/mrt /tmp/exe

Regards

Gull04

Why not simply

installdir=${1//\\\\n/ }

?

2 Likes

Nice RudiC, if OP needs support for both double and single quotes on call:

#!/bin/ksh
install_dir=${1//\\\\n/ }
install_dir=${install_dir//\\n/ }
printf "DIRR_PATH:%s\n" $install_dir
echo "Desired Output:$install_dir"
$ ./loopissue.sh '/tmp/scripts\\n/tmp/mrt\\n/tmp/exe'
DIRR_PATH:/tmp/scripts
DIRR_PATH:/tmp/mrt
DIRR_PATH:/tmp/exe
Desired Output:/tmp/scripts /tmp/mrt /tmp/exe

$ ./loopissue.sh "/tmp/scripts\\n/tmp/mrt\\n/tmp/exe"
DIRR_PATH:/tmp/scripts
DIRR_PATH:/tmp/mrt
DIRR_PATH:/tmp/exe
Desired Output:/tmp/scripts /tmp/mrt /tmp/exe

Getting error:

--- Post updated at 02:53 AM ---

@Gull04: I tried your option but i get -e -e before the first element. Please see output below:

Hi,

Try running without the -e switch, it's a long time since I worked on AIX.

As in;

#!/bin/ksh
VAR1=`echo "${1}" | sed -e "s/'//g"`
echo "${VAR1}" |
  while IFS=' '
read -r dirpath
do
  echo "DIRR_PATH:$dirpath"
  install_dir=$install_dir" "$dirpath
done
echo "Desired Output:$install_dir"

Regards

Gull04

If parameter $1 contains literal \\n then you can use sed to convert to a space

VAR1=$(printf "%s\n" "$1" | sed 's/\\\\n/ /g')

The \ and \n are really special. Some explanations:
I used ' ' because the shell treats \ literally in them - in contrast to " " .
I used $( ) because the shell does not mistreat \ in them - in contrast to ` ` .
I used printf "%s\n" because the ksh builtin echo treats \n in a special way.
Of course I put the $1 in "quotes" to have variable substitution but no further expansions. Note that a literal \ in " " is special but not if it stems from a variable substitution.
So sed sees s/\\\\n/ /g , and treats each \\ as one \

1 Like

Hi,

Thanks for the detailed explanation, such things are always worth while for mw.

Regards

Gull04

@Gull04 removing -e works. Thank you for the inputs.
@MadeInGermany I will try you suggestions tomorrow.

Moderator comments were removed during original forum migration.