33
votes
Accepted
Escape a variable for use as content of another script
TL;DR: skip to the conclusion.
While several shells/tools have builtin quoting operators some of which have already been mentioned in a few answers, I'd like to stress here that many are unsafe to use ...
30
votes
Escape a variable for use as content of another script
Bash provides a printf builtin with %q format specifier, which performs shell escaping for you, even in older (<4.0) versions of Bash:
printf '[%q]\n' "Ne'er do well"
# Prints [Ne\'er\ do\ well]
...
24
votes
Accepted
Is it possible to print the content of the content of a variable with shell script? (indirect referencing)
You can accomplish this using bash's indirect variable expansion (as long as it's okay for you to leave out the $ from your reference variable):
$ var=test
$ test="my string"
$ echo "$var"
test
$ ...
21
votes
Accepted
Why arithmetic syntax error in bash causes exit from the function?
POSIX requires that expansion errors exit non-interactive shells (and produce an error message).
A syntax error upon arithmetic expansion is an expansion error
When in POSIX mode like when ...
20
votes
Accepted
Glob character within variable expands in bash but not zsh
That would be the first time I see anybody complaining about that (we more often see people complaining about it not doing word splitting upon parameter expansion).
Most people expect
echo $file
to ...
20
votes
Accepted
What does the substitution ${!var_name+x} mean?
In the bash shell, ${!var} is a variable indirection. It expands to the value of the variable whose name is kept in $var.
The variable expansion ${var+value} is a POSIX expansion that expands to ...
20
votes
Accepted
Bash echo $-1 prints hb1. Why?
You are not asking it to print the 1st argument, that would be: $1.
What you are asking for is a special parameter:
-
($-, a hyphen.) Expands to the current option flags as specified upon ...
18
votes
Accepted
Bash: Extract one of the four sections of an IPv4 address
Assuming the default value of IFS you extract each octet into it's own variable with:
read A B C D <<<"${IP//./ }"
Or into an array with:
A=(${IP//./ })
17
votes
Accepted
printf - store formatted string output in a variable
Bash (since 3.1), zsh (since 5.3) and ksh93 (since v- and u+m 2021-11-28) have an "assignment to variable option" for printf:
$ Row='%s\t%s\t%s\t%s\n'
$ printf -v Result -- "${Row}&...
14
votes
Accepted
Using curly braces to process colon-separated variables
The ksh-style (and now specified by POSIX for sh) ${var#pattern} and ${var%pattern} (and greedy variants with ## and %%) only remove text from the beginning and end respectively of the contents of the ...
13
votes
Accepted
Is `echo $TEST` expanding an asterisk in the variable a bug?
No, it is not a bug. You have shown that
echo '*'
will produce a literal *. Hence when you substitute this output, as per the following command
TEST=$(echo '*')
it will put * into the variable $TEST....
12
votes
Accepted
Word splitting in positional parameters
Word splitting only applies to unquoted expansions (parameter expansion, arithmetic expansion and command substitution) in modern Bourne-like shells (in zsh, only command substitution unless you use ...
11
votes
Is it possible to print the content of the content of a variable with shell script? (indirect referencing)
For the case when the variable name contained in var is prefixed with $ you may use eval:
$ var='$test'
$ test="my string"
$ eval echo $var
my string
What happens here:
bash expands $var to the value ...
11
votes
Using parameter substitution on a Bash array
As far as I can see, there's no need to read it into a bash array to create that output:
$ sed 's/[ "]//g; s/,/ /; s/,//g; s/ /,/; s/.*/|ELEMENT|&|/' <file
|ELEMENT|10,this|
|ELEMENT|20,is|
|...
10
votes
Reference bash variable from a variable
If you shell supports the ${!varname} form of indirect references, you can do (as suggested by @Barmar):
$ foobar_darwin_amd64=pinto
$ package=foobar
$ varname="${package}_darwin_amd64"
$ echo ${!...
10
votes
Accepted
calling other variables in a variable name (Bash)
langs is not an array but a string in your code.
To make it an array and use it:
langs=( EN GE )
dir_EN=/xx
dir_GE=/zz
dir_ml=()
for i in "${langs[@]}"; do
declare -n p="dir_$i"
dir_ml+=( "$...
10
votes
Keep matching pattern in shell parameter expansion
${var%"${var##pattern}"}
${var#"${var%%pattern}"}
Example:
$ k='ab*10cd20ef*'
$ echo "${k%"${k##*[0-9]}"}"
ab*10cd20
$ echo "${k#"${k%%[0-9]*}"}&...
9
votes
Why is my variable local in one 'while read' loop, but not in another seemingly similar loop?
As mentioned in other answers, the parts of a pipeline run in subshells, so modifications made there aren't visible to the main shell.
If we consider just Bash, there are two other workarounds in ...
9
votes
Accepted
Behaviour of bash command substitution with command from string in variable
Word splitting happens quite late in the evaluation of a command. Most crucially for you, it happens after variable expansion and command substitution.
This means that the second line in
s="echo ...
9
votes
${p:2:1} Meaning in the shell script
That is a parameter expansion (Bash manual), in particular of the form:
${parameter:offset:length}
which is described as "substring expansion". It extracts characters from the variable ...
9
votes
Is it possible to print the content of the content of a variable with shell script? (indirect referencing)
Similar to Jesse_b's answer, but using a name reference variable instead of variable indirection (requires bash 4.3+):
$ declare -n var=test
$ test="my string"
$ echo "$var"
my string
The name ...
9
votes
Accepted
Using parameter substitution on a Bash array
I would remove what you need to remove using sed before loading into the array (also note the lower case variable names, in general it is best to avoid capitalized variables in shell scripts):
#!/bin/...
9
votes
Using parameter substitution on a Bash array
ELEMENT='50,n,e,e,d,2'
IFS=, read -r first rest <<<"$ELEMENT"
printf "%s,%s\n" "$first" "${rest//,/}"
50,need2
Get out of the habit of using ALLCAPS variable names. You'll eventually collide ...
9
votes
Is there a way to expand a variable into multiple arguments without globbing in bash?
Use an array and quote it:
expression=('-type' 'f' '-name' '*.csv' '-mtime' '+14')
find /var/data "${expression[@]}" -delete -print
Each element will expand separately but without ...
9
votes
Accepted
How does the tilde expansion work within a shell variable?
The bash shell will not expand ~ when the tilde is part of the result of a variable expansion. The unquoted tilde prefix (~, ~+ or ~username for the current user named username) is only expanded to ...
8
votes
Why is there a number in the zsh parameter expansion ${1-$PWD}
That's not brace expansion, that's a standard parameter expansion operator (dates back to the Bourne shell in the 70s).
${1-$PWD}
Expands to the value of $1 (the first positional parameter) if it is ...
8
votes
Behaviour of bash command substitution with command from string in variable
After some reading I try to answer by myself
Why does command substitution behave in such way?
$ a='echo x; echo y'
$ echo $($a) # expect 'x y'
Command substitution
Lets notice that the substitution ...
8
votes
Double and triple substitution in bash and zsh
{ba,z}sh solution
Here's a function which works in both {ba,z}sh. I believe it's also POSIX compliant.
Without going mad with quoting, you can use it for many levels of indirection like so:
$ a=b
$ b=...
8
votes
Bash: Extract one of the four sections of an IPv4 address
Your problem statement may be a bit more liberal than you intended.
At the risk of exploiting a loophole,
here’s the solution muru alluded to:
first=${IP%%.*}
last3=${IP#*.}
second=${last3%%.*}
...
Only top scored, non community-wiki answers of a minimum length are eligible
Related Tags
variable-substitution × 340bash × 196
shell-script × 89
shell × 60
variable × 53
zsh × 24
quoting × 24
command-substitution × 17
sed × 15
wildcards × 15
brace-expansion × 13
awk × 12
string × 12
command-line × 10
scripting × 10
environment-variables × 10
parameter × 10
ksh × 9
array × 9
grep × 8
find × 8
linux × 7
for × 7
function × 6
arguments × 6