I know the whole language is confusing, but I am having trouble understanding assignments with command substitutions:  x=Example sentence                  #1 fails due to space x='Example sentence'                #2 ok  echo $x                             #3 ok [ -n $(echo $x) ]  &amp;&amp; echo foo      #4 fails due to space [ -n "$(echo $x)" ]  &amp;&amp; echo foo    #5 ok y=$x                                #6 ok y=$(echo $x)                        #7 ok, not like 1? [ -n $y ]                           #8 fails due to space    With practice, I have learned that command substitutions in tests should always be surrounded by quotes (e.g. [ -n "$(cmd)" ]), and that quotes can be used inside the substitution without interfering with outside quotes. Quoting a substitution seems to capture stdout, but not stderr (unless redirected).  Q1. But what happens when the substitution is not quoted (cases 4 and 7)?   Specifically, I am confused with the apparent difference in behaviour between assignments x=$(cmd), which seem to work fine with spaces, versus tests [ -n $(cmd) ], which seem to always be truthy.  Q2. Is it bad practice to assign command substitutions without quotes x=$(cmd)? Should I always quote them x="$(cmd)"?
121958
I've read that you need double quotes for expanding variables, e.g.  if [ -n "$test" ]; then echo '$test ok'; else echo '$test null'; fi   will work as expected, while  if [ -n $test ]; then echo '$test ok'; else echo '$test null'; fi   will always say $test ok even if $test is null.  but then why don't we need quotes in echo $test?
778
Usually, $0 in a script is set to the name of the script, or to whatever it was invoked as (including the path). However, if I use bash with the -c option, $0 is set to the first of the arguments passed after the command string:  bash -c 'echo $0' foo bar  # foo    In effect, it seems like positional parameters have been shifted, but including $0. However shift in the command string doesn't affect $0 (as normal):  bash -c 'echo $0; shift; echo $0' foo bar # foo # foo   Why this apparently odd behaviour for command strings? Note that I am looking for the reason, the rationale, behind implementing such odd behaviour.     One could speculate that such a command string wouldn't need the $0 parameter as usually defined, so for economy it is also used for normal arguments. However, in that case the behaviour of shift is odd. Another possibility is that $0 is used to define the behaviour of programs (a la bash called as sh or vim called as vi), but that cannot be, since $0 here is only seen in the command string and not by programs called within it. I cannot think of any other uses for $0, so I am at a loss to explain this.
23266
I just saw this in an init script: echo $&quot;Stopping Apache&quot;  What is that dollar-sign for? My research so far: I found this in the bash manual:  extquote  If set, $'string' and $&quot;string&quot; quoting is performed within ${parameter} expansions enclosed in double quotes.  This option is enabled by default.   ...but I'm not finding any difference between strings with and without the $ prefix: $ echo &quot;I am in $PWD&quot; I am in /var/shared/home/southworth/qed $ echo $&quot;I am in $PWD&quot; I am in /var/shared/home/southworth/qed $ echo $&quot;I am in ${PWD}&quot; I am in /var/shared/home/southworth/qed $ echo &quot;I am in ${PWD}&quot; I am in /var/shared/home/southworth/qed $ echo 'I am in ${PWD}' I am in ${PWD} $ echo $'I am in ${PWD}' I am in ${PWD} $ echo $'I am in $PWD' I am in $PWD
96788
I'm sure this is posted somewhere, but I haven't been able to find it.  In Bash, how does one specify operator precedence (aka command grouping) without creating a subshell?  In most other languages the() do this, but in Bash this runs the commands in a subshell which "discards" environment changes.  I want to specify operator precedence without losing environment changes.    Specifically, I'd like to do something like this and have the entire script exit, not just the subshell in the ():  die () {     echo "[DIE]: $1"     exit 1 }  # When installChruby returns an error, print the error message and exit [[ $CHRUBY =~ [Yy] ]] &amp;&amp; (installChruby || die "Error installing chruby")   I figured out a "workaround" by doing this, but it's not a pretty one-liner like I want:  if [[ $CHRUBY =~ [Yy] ]]; then installChruby || die "Error installing Chruby"; fi    The desired outcome is to do nothing and continue if CHRUBY is unset, to call the function installChruby if CHRUBY is either Y or y, and to call the die function only if the installChruby function returns false.   Is there an operator in Bash that does this besides (), or is there a way to tell the code inside the () to not run in a sub-shell?
107731
I'm learning Bash, and I want to replace space characters with other "non blank" characters. I'm using a for loop:  for f in *\ *; do mv "$f" "${f// /_}"; done   My question is, why are the double slash and the space in ${f// /_}? What does ${f// /_} do?
6324
Sometimes I see shell scripts use all of these different ways of quoting some text: &quot;...&quot;, '...', $'...', and $&quot;...&quot;. Why are there so many different kinds of quote being used? Do they behave differently or affect what I can do inside them?
8187
Writing my first script so I'm sure this is a basic question, but can someone please explain to me why I can:  cd ~ cd bin cd ~/bin cd 'bin'   But not  cd '~' cd '~/bin'   I need to cd to a directory path with a space in one of the directory names, so I need the quotes (it's Windows Program Files under wine). I can get around it with two cd commands, but why can't I put ~ in quotes?  If I type cd '~' (or cd "~") I get:  bash: cd: ~: No such file or directory
24683
I was wondering how to understand the following:     Piping the stdout of a command into the stdin of another is a powerful   technique. But, what if you need to pipe the stdout of multiple   commands? This is where process substitution comes in.   In other words, can process substitution  do whatever pipe can do?   What can process substitution do, but pipe cannot?
51349
Can I safely omit quotes on the right side of a local assignment?  function foo {     local myvar=${bar}     stuff() }   I'm mainly interested in bash, but any info on corner cases in other shells are welcome.
31975
What can explain the examples below and how do I fix this, preferably without heavy quoting acrobatics? I am using the $n to simulate multiple line command strings, just in case it distracts you from the real question.  ~$ n=$'\n'; sudo -i echo "line1${n}line2${n}" line1line2 ~$   but  ~$ n=$'\n'; sudo echo "line1${n}line2${n}" line1 line2  ~$
3880
How would I go about replacing all of the double quotes in my batch file's parameters with escaped double quotes? This is my current batch file, which expands all of its command line parameters inside the string:  @echo off call bash --verbose -c "g++-linux-4.1 %*"   It then uses that string to make a call to Cygwin's bash, executing a Linux cross-compiler. Unfortunately, I'm getting parameters like these passed in to my batch file:  "launch-linux-g++.bat" -ftemplate-depth-128 -O3 -finline-functions  -Wno-inline -Wall  -DNDEBUG   -c  -o "C:\Users\Me\Documents\Testing\SparseLib\bin\Win32\LinuxRelease\hello.o"  "c:\Users\Me\Documents\Testing\SparseLib\SparseLib\hello.cpp"   Where the first quote around the first path passed in is prematurely ending the string being passed to GCC, and passing the rest of the parameters directly to bash (which fails spectacularly.)  I imagine if I can concatenate the parameters into a single string then escape the quotes it should work fine, but I'm having difficulty determining how to do this. Does anyone know?
12613
I often see tutorials on the web or posts on this site which make heavy use of the following characters at the command line. Often it seems that they are used for pretty similar purposes. What are the differences between them when used on the command line or for shell programming? For what purpose do I use which of them?  " " double quotes  ' ' single quotes  ` ` backticks
15664
I have a text file named links.txt which looks like this  link1 link2 link3   I want to loop through this file line by line and perform an operation on every line. I know I can do this using while loop but since I am learning, I thought to use a for loop. I actually used command substitution like this   a=$(cat links.txt)   Then used the loop like this  for i in $a; do ###something###;done   Also I can do something like this  for i in $(cat links.txt); do ###something###; done   Now my question is when I substituted the cat command output in a variable a, the new line characters between link1 link2 and link3 are removed and is replaced by spaces  echo $a   outputs  link1 link2 link3  and then I used the for loop. Is it always that a new line is replaced by space when we do a command substitution??  Regards
89914
Examples  I've recently found examples of using pairs of enclosing braces {}, with nothing in between the opening and closing braces, as arguments to commands and even to their options:  cat foo | xargs -I{} echo {}  find . -size 0 -exec rm -i {} \;  No Documentation  My problem is that I cannot find a documentation in the  that describes the usage of {} in such context as in the examples above.  I do not think it is a , because a dollar sign must precede the enclosing braces in a parameter expansion as in ${}.  It cannot be a  either, because it takes the form of {x..y[..incr]}, where x and y are not optional.  It also cannot be a  either, because {} is used as arguments.  Questions   What does a pair of enclosing braces {} even mean, in general, as an argument to any command that accepts it? Where can I find a documentation that describes the usage of {} as arguments?
1646
The following script does not behave as I would have expected.  Adding spaces around the '=' in the conditional made it perform how I wanted, but it got me thinking, what is it actually doing inside the conditional?  #!/bin/bash S1='foo' S2='bar' if [ $S1=$S2 ]; then     echo "S1('$S1') is equal to S2('$S2') fi echo $S1 echo $S2   The output is:  S1('foo') is equal to S2('bar') foo bar   The contents of S1 and S2 don't change from what they are assigned, so the = doesn't perform an assignment.
112657
I know I can solve this problem several ways, but I'm wondering if there is a way to do it using only bash built-ins, and if not, what is the most efficient way to do it.  I have a file with contents like  AAA B C DDD FOO BAR   by which I only mean it has several lines and each line may or may not have spaces.  I want to run a command like  cmd AAA "B C DDD" "FOO BAR"   If I use cmd $(&lt; file) I get  cmd AAA B C DDD FOO BAR   and if I use cmd "$(&lt; file)" I get  cmd "AAA B C DDD FOO BAR"   How do I get each line treated a exactly one parameter?
21438
In  we learned how to use \newcommand within a command definition with another \newcommand, when the name of the inner command needs to contain a parameter of the outer command. Now, suppose I want to do the same, but for the inner \newcommand to also have parameters, i.e. I want the following code to work:  \newcommand{\defsilly}[1]{%   % define a command named silly#1 , taking a single parameter } \defsilly{willy} \sillywilly{theparameter}   Motivation: I'm writing a thesis document class, which has a bunch of the following kind of command pairs:  \newcommand{\iitthesis@authorEnglish}{Name of Author} \newcommand{\authorEnglish}[1]{\renewcommand{\iitthesis@authorEnglish}{#1}}   I want to replace each of these pairs with something like:  \iitthesis@thesisdatafield{authorEnglish}{Name of Author}   This defines both the above commands.