0

I can't find out, how to mask the $ in the following shell statement. Any help is appreciated!

#!/bin/bash
    
local result=`su -m user1 -c "sqlplus -s / as sysdba <<-EOF
  SELECT cdb FROM v\$database;
  exit
EOF"
`
paddy3k
  • 149
  • 1
  • 11

2 Answers2

2

You should single-quote EOF, e.g. <<-'EOF'

But then you also need to run the subprocess with $() instead of backquotes.

#!/bin/bash
    
local result=$(su -m user1 -c "sqlplus -s / as sysdba <<-'EOF'
  SELECT cdb FROM v\$database;
  exit
EOF")

BashFAQ/082 reports that “Backslashes (\) inside backticks are handled in a non-obvious manner”

$ echo "`echo \\a`" "$(echo \\a)"
a \a
$ echo "`echo \\\\a`" "$(echo \\\\a)"
\a \\a
# Note that this is true for *single quotes* too!
$ foo=`echo '\\'`; bar=$(echo '\\'); echo "foo is $foo, bar is $bar" 
foo is \, bar is \\

So if you do not want to use $(...) you need 2 backslashes, i.e. \\$database and if you want to use neither $(...) nor single-quoted EOF, you need no less than 6 backslashes, i.e. \\\\\\$database

vdavid
  • 2,434
  • 1
  • 14
  • 15
1

Do not use backticks. Use #(...).

local result=$(su -m user1 -c "sqlplus -s / as sysdba <<-EOF
  SELECT cdb FROM v\\\$database;
  exit
EOF
")

But anyway, if you do not want anything to expand, use single quotes.

local result=$(su -m user1 -c 'sqlplus -s / as sysdba <<-EOF
  SELECT cdb FROM v\$database;
  exit
EOF
')

And you could, redirect in the parent shell - it's going to be way simpler - and use a quoted stop word.

local result=$(su -m user1 -c 'sqlplus -s / as sysdba' <<-'EOF'
  SELECT cdb FROM v$database;
  exit
EOF
")
KamilCuk
  • 120,984
  • 8
  • 59
  • 111