Using a Command That Needs Backticks to Be Passed as Part of an Argument in Bash

Using a command that needs backticks to be passed as part of an argument in bash

Inside double quotes, backticks are being interpreted by shell, resulting in table being treated as a command. You need to escape them:

hive -e "alter table ${database}.\`${table}\` SET TBLPROPERTIES('EXTERNAL'='FALSE')"

Alternatively, you can use a variable to hold the backticks:

bt="\`"
hive -e "alter table ${database}.$bt${table}$bt SET TBLPROPERTIES('EXTERNAL'='FALSE')"

The issue with your second command

hive -e "alter table ${database}.$(table) SET TBLPROPERTIES('EXTERNAL'='FALSE')"

is that the construct $(table) works the same way as table inside backticks - it is just a better way of doing command substitution in Bash. Hence you get the same error as earlier.


Related posts:

  • Difference between single and double quotes in Bash
  • What is the benefit of using $() instead of backticks in shell scripts?

Using a command that needs backticks to be passed as part of an argument in bash

Inside double quotes, backticks are being interpreted by shell, resulting in table being treated as a command. You need to escape them:

hive -e "alter table ${database}.\`${table}\` SET TBLPROPERTIES('EXTERNAL'='FALSE')"

Alternatively, you can use a variable to hold the backticks:

bt="\`"
hive -e "alter table ${database}.$bt${table}$bt SET TBLPROPERTIES('EXTERNAL'='FALSE')"

The issue with your second command

hive -e "alter table ${database}.$(table) SET TBLPROPERTIES('EXTERNAL'='FALSE')"

is that the construct $(table) works the same way as table inside backticks - it is just a better way of doing command substitution in Bash. Hence you get the same error as earlier.


Related posts:

  • Difference between single and double quotes in Bash
  • What is the benefit of using $() instead of backticks in shell scripts?

Is it possible to pass a variable to a command inside ` `

Yes! You can use:

while read zonename
do
...
done < <(lufslist "$be_name")

Note the difference between yours

done < <(`lufslist $be_name`)

and

done < <(lufslist "$be_name")

the () makes the command to be executed in a subshell, so you do not have to use the ` character to call it.

Also, it is always good to call your variables enclosed in double quotes: lufslist "$be_name".

Example

$ info="1 month ago"
$ while read a; do echo $a; done < <(date -d"$info")
Wed Sep 18 15:00:59 CEST 2013

Backticks vs braces in Bash

The `` is called Command Substitution and is equivalent to $() (parenthesis), while you are using ${} (curly braces).

So all of these expressions are equal and mean "interpret the command placed inside":

joulesFinal=`echo $joules2 \* $cpu | bc`
joulesFinal=$(echo $joules2 \* $cpu | bc)
# v v
# ( instead of { v
# ) instead of }

While ${} expressions are used for variable substitution.

Note, though, that backticks are deprecated, while $() is POSIX compatible, so you should prefer the latter.


From man bash:

Command substitution allows the output of a command to replace the
command name. There are two forms:

          $(command)
or
`command`

Also, `` are more difficult to handle, you cannot nest them for example. See comments below and also Why is $(...) preferred over ... (backticks)?.

How to use backtick command result with sed?

You can embed $(...) within double-quotes, but not in single-quotes:

sed -i "s/%VERSION%/$(date)/" test.txt && cat test.txt

(Same as `...` but you shouldn't use that obsolete syntax, $(...) is better.)


Btw, for testing purposes, it's better to use sed without -i,
so the original file is not modified:

sed "s/%VERSION%/$(date)/" test.txt

As a side note, and this is a completely different discussion,
but worth mentioning here.
This may look like it should work but it doesn't, and you may wonder why:

DD=$(date) sed -i "s/%VERSION%/$DD/" test.txt && cat test.txt

Why it doesn't work?
Because the $DD embedded in the "..." is evaluated at the time the command is executed.
At that time the value of DD is not set to the output of $(date).
In the "..." it will have whatever value it had before executing the command.
For the sed process, the value DD with the output of $(date) is visible,
but sed doesn't use that, because why would it.
The "..." passed to sed is evaluated by the shell, not by sed.

bash echo with escape backtick and $

The expression is evaluated on assignment.

COMMAND1="Build `date`"

The `...` is a command substitution and is deprecated in favor of $( ... ) style. The " doublequotes are used to allow the text to be expanded. So first this command is expanded to:

COMMAND1='Build Wed Dec 26 21:09:43 UTC 2018'

Then the assignment happens. You can't retrieve later what command was used to declare the variable. That information is lost. If you have some upstream - it needs to pass this information to you along.

If you wish for COMMAND1 to contain the string (literally)

Build `date`

You can use single quotes:

COMMAND1='Build `date`'

You can later use some combination of eval or similar to expand the variable, however I would suggest to just do a function

COMMAND1() {
Build $(date)
}

echo "COMMAND1 is declared as:"
declare -f COMMAND1
echo "COMMAND1 execution returns: $(COMMAND1)"

Helpful links:

  • Quotes
  • Eval command and security issues
  • Why is $(...) preferred over ... (backticks)?

Perl backticks using bash

Capture::Tiny is a very nice option: as the SYNOPSIS shows, you can do

use Capture::Tiny 'capture';
my ($output, $error_output, $exit_code) = capture {
system(@whatever);
};

as well as using system inside capture_stdout if you want the simpler behavior of backticks.

Plus it's very general-purpose, working on Perl code (even Perl code that does weird stuff) as well as external programs, so it's a good thing to have in your toolbox.

Passing a bash script variable to a quoted value in backticks

Ok,

I got it in the end. So

  1. I have an alias which points to the bash file. The file receives a variable which must be passed in quotes:

$jiraReleases "Version1.2.3"


  1. The file takes the variable:

JIRA_FIXVERSION=$1


  1. Wthin jq the quotes are escaped, and additional quotes and apostrophes are added. Note that the below line is also surrounded by single quotes and backticks.

.[] | {id,name} | select(.name=='\""${JIRA_FIXVERSION}"\"')

Why doesn't my if statement with backticks work properly?

What you want is

if cp -i "$file" "$destination"; then #...

Don't forget the quotes.


You version:

if [ `cp -i $files $destination` ];then #..

will always execute the else branch.

The if statement in the shell takes a command.
If that command succeeds (returns 0, which gets assigned into $?), then the condition succeeds.

If you do if [ ... ]; then, then it's the same as
if test ... ; then because [ ] is syntactic sugar for the test command/builtin.

In your case, you're passing the result of the stdout* of the cp operation as an argument to test

The stdout of a cp operation will be empty (cp generally only outputs errors and those go to stderr). A test invocation with an empty argument list is an error. The error results in a nonzero exit status and thus you always get the else branch.


*the $() process substitution or the backtick process substitution slurp the stdout of the command they run



Related Topics



Leave a reply



Submit