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
- 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"
- The file takes the variable:
JIRA_FIXVERSION=$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 asif 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
What Is the Use of Gfp_User Flag in Kmalloc
How to Use a Seq_File in Linux Kernel Modules
How to Remove the Last Character of the Last Line of a File
How to Join a Thread in Linux Kernel
Shell Command to Update Pom File from a Variable
What Does Version Info in Ldd -V Mean
Git Clone from Linux to Tfs Git Repo
Perl: What Does Checkstack.Pl in Linux Source Do
Linux Iterate Over Files in Directory
How to Fetch the Tags for Ec2-Describe-Instances in a Shell Script
How to Change the Watchdog Timer in Linux Embedded
Run a Command Conditionally with Netcat and Grep
Spell Checking a File Using Command Line, Non-Interactively