stephen cheng
stephen cheng

Reputation: 99

shell function issue - remove the single quote from shell statement

I am getting a issue running below command:

when I run: cmssh 12np, I meant to invoke the defined function cmssh, eventually I am expecting a shell command line like this:

sshpass -p password ssh mydomain\\[email protected]

, see below source:

alias 12np='ssh mydomain\\stephencheng@[email protected]'


function cmssh () {
   set -x
   local aliascmd=$1
   cmdstr=$(alias $aliascmd | cut -d'=' -f2 | cut -d"'" -f2)
   echo $cmdstr
   sshpass -p "$cmpw" $cmdstr
   #debug cmdstr : sshpass -p password 'ssh mydomain\\[email protected]'
}

however, the final step always render the result as:

sshpass -p password 'ssh mydomain\\[email protected]'

I have attempted many ways to try to remove the single quote, but got no idea how it is possible.

See the debug info:

~  cmssh 12np
+cmssh:2> local 'aliascmd=12np'
+cmssh:4> cmdstr=+cmssh:4> alias 12np
+cmssh:4> cmdstr=+cmssh:4> cmdstr=+cmssh:4> cut '-d=' -f2
+cmssh:4> cut '-d'\' -f2
+cmssh:4> cmdstr='ssh mydomain\\[email protected]'
+cmssh:7> echo 'ssh mydomain\\[email protected]'
ssh mydomain\\[email protected]
+cmssh:8> sshpass -p password 'ssh mydomain\\[email protected]'
sshpass: Failed to run command: No such file or directory

Thanks

Upvotes: 5

Views: 337

Answers (2)

mklement0
mklement0

Reputation: 440337

Note: At this point it is not clear what specific shell the OP uses. This answer makes a general point and then discusses bash and zsh.

Your immediate problem is unrelated to quoting: The error message suggests that the executable sshpass is not in your $PATH.

Your string ($cmdstr) doesn't actually contain single quotes - they are an artifact of running bash or zsh with set -x in effect.

However, there are additional issues:


The way you parse the alias definition in cmssh() turns the \\ in your alias definition from a (conceptually) quoted single \ into literal string \\ (two literal \ chars.)

A simple fix in this case is to add another layer of evaluation by having xargs (without arguments) echo the string:

cmdstr=$(alias $aliascmd | cut -d"'" -f2 | xargs)

Note that I've eliminated the =-based cut command, which is not needed.

In general, though, parsing alias definitions this way is fragile.

At that point I would expect your code to work in bash, though not yet in zsh (see below). Note that simply removing function  from the beginning of your function definition would make your code work in sh (a POSIX-features-only shell), too.


The final problem affects only zsh, not bash:

zsh by default doesn't perform word splitting on $cmdstr in the sshpass -p "$cmpw" $cmdstr command, so that 'ssh mydomain\[email protected]' is passed as a SINGLE argument to sshpass.

To turn on word splitting when evaluating $cmdstr and thus pass its tokens as separate arguments, refer to it as ${=cmdstr}:

sshpass -p "$cmpw" ${=cmdstr}

Note that this feature is zsh-specific.

Upvotes: 1

Sireesh Yarlagadda
Sireesh Yarlagadda

Reputation: 13736

Try this

mydomain="'ssh mydomain\\[email protected]'"

echo ${mydomain/#'/\\\'} \\ assign this variable 

Other way to do this,using sed

echo $mydomain | sed -s "s/^\(\(\"\(.*\)\"\)\|\('\(.*\)'\)\)\$/\\3\\5/g"

Upvotes: 0

Related Questions