Is this a Bash bug?  $ mkdir test &amp;&amp; cd test &amp;&amp; echo "a" &gt; "some.file" test$ echo '*' * test$ TEST=$(echo '*') test$ echo $TEST some.file   Why is the second output the resolution of * into (all) filenames instead of just a literal * output? Looks like a bug in Bash?  Tried on Ubuntu 18.04, bash version 4.4.19(1)-release. Expect it will be the same on other OS'es.
1847
Or, an introductory guide to robust filename handling and other string passing in shell scripts.  I wrote a shell script which works well most of the time. But it chokes on some inputs (e.g. on some file names).  I encountered a problem such as the following:   I have a file name containing a space hello world, and it was treated as two separate files hello and world. I have an input line with two consecutive spaces and they shrank to one in the input. Leading and trailing whitespace disappears from input lines. Sometimes, when the input contains one of the characters \[*?, they are replaced by some text which is is actually the name of files. There is an apostrophe ' (or a double quote ") in the input and things got weird after that point. There is a backslash in the input (or: I am using Cygwin and some of my file names have Windows-style \ separators).   What is going on and how do I fix it?
51790
I have a bash shell script that loops through all child directories (but not files) of a certain directory.  The problem is that some of the directory names contain spaces.    Here are the contents of my test directory:  $ls -F test Baltimore/  Cherry Hill/  Edison/  New York City/  Philadelphia/  cities.txt   And the code that loops through the directories:  for f in `find test/* -type d`; do   echo $f done   Here's the output:   test/Baltimore test/Cherry Hill test/Edison  test/New York City test/Philadelphia   Cherry Hill and New York City are treated as 2 or 3 separate entries.  I tried quoting the filenames, like so:  for f in `find test/* -type d | sed -e 's/^/\"/' | sed -e 's/$/\"/'`; do   echo $f done   but to no avail.  There's got to be a simple way to do this.    The answers below are great.  But to make this more complicated - I don't always want to use the directories listed in my test directory.  Sometimes I want to pass in the directory names as command-line parameters instead.  I took Charles' suggestion of setting the IFS and came up with the following:  dirlist="${@}" (   [[ -z "$dirlist" ]] &amp;&amp; dirlist=`find test -mindepth 1 -type d` &amp;&amp; IFS=$'\n'   for d in $dirlist; do     echo $d   done )   and this works just fine unless there are spaces in the command line arguments (even if those arguments are quoted).  For example, calling the script like this: test.sh "Cherry Hill" "New York City" produces the following output:   Cherry Hill New York City
113284
I have a file called -.  I want to display its contents.  One way is to do  cat ./-   since cat - reads from standard input. However, why are cat "-" and cat '-' also interpreted by the shell as cat -?
723
I am trying to understand how exactly Bash treats the following line:  $(&lt; "$FILE")   According to the Bash man page, this is equivalent to:  $(cat "$FILE")   and I can follow the line of reasoning for this second line. Bash performs variable expansion on $FILE, enters command substitution, passes the value of $FILE to cat, cat outputs the contents of $FILE to standard output, command substitution finishes by replacing the entire line with the standard output resulting from the command inside, and Bash attempts to execute it like a simple command.  However, for the first line I mentioned above, I understand it as: Bash performs variable substitution on $FILE, Bash opens $FILE for reading on standard input, somehow standard input is copied to standard output, command substitution finishes, and Bash attempts to execute the resulting standard output.  Can someone please explain to me how the contents of $FILE goes from stdin to stdout?
5113
I have file1.txt    this is the original text   line2   line3   line4   happy hacking !     and file2.txt    this is the original text   line2   line4   happy hacking !   GNU is not UNIX     if I do: diff file1.txt file2.txt I get:    3d2   &lt; line3   5a5   &gt; GNU is not UNIX     How is the output generally interpreted? I think that &lt; means removed but what do 3d2 or 5a5 mean?  If I do:    $ diff -u file1.txt file2.txt   --- file1.txt        2013-07-06 17:44:59.180000000 +0200   +++ file2.txt        2013-07-06 17:39:53.433000000 +0200   @@ -1,5 +1,5 @@    this is the original text    line2   -line3    line4    happy hacking !   +GNU is not UNIX     The results are clearer but what does @@ -1,5 +1,5 @@ mean?
60654
The question is about special variables. Documentation says:     !!:$      designates the last argument of the preceding command. This may   be shortened to !$.        ($_, an underscore.) At shell startup, set to the absolute pathname used  to invoke the shell or shell script being executed as passed in the    environment or argument list. Subsequently, expands to the last argument to the previous command after expansion. Also set to the full pathname  used to invoke each command executed and placed in the environment    exported to that command.    There must be some difference I cannot catch, because:  $ echo "hello" &gt; /tmp/a.txt $ echo "!$" echo "/tmp/a.txt" /tmp/a.txt  $ echo "hello" &gt; /tmp/a.txt $ echo $_ hello   What is the difference?
103738
For a command, if using - as an argument in place of a file name will mean STDIN or STDOUT.   But in this example, it creates a file with the name -:  echo hello &gt; -   How can I make - in this example mean STDOUT? Conversely, how can I make - mean a file named - in examples such as:  cat -
8122
In bash, calling foo would display any output from that command on the stdout.  Calling foo &gt; output would redirect any output from that command to the file specified (in this case 'output').  Is there a way to redirect output to a file and have it display on stdout?
109280
Consider the two shell samples  $ ls myDoc.html SomeDirectory someDoc.txt   and  $ echo $(ls) myDoc.html SomeDirectory someDoc.txt   The first executes ls which, as I understand, appends the contents of the current working directory to the stdout file (which is what the terminal displays).  Is this correct?  The second takes the value of the ls command (which means is the contents of the current working directory) and prints it to the stdout file. Is this correct?  Why do the two commands give different outputs?
65564
Why does Ubuntu create a file ending in ~ for every file I create with a text editor ?   Creating a file with a text editor like GNU Emacs, say myfile, another file called myfile~ is also created. Why is this superfluous file created ? Using cat on it displays nothing.  Thanks,
95704
I noticed while answering another question that test and [ are different binaries, but the [ manpage pulls up test's. Besides the requirement for an ending ], is there any difference?  If not, why are they separate binaries instead of being symlinked? (They are also bash builtins, and bash doesn't show a difference either.)
98935
I have a sample script (credit goes to ):  #!/bin/bash cat &lt;(cat /etc/lsb-release)   I save this script as somename.sh in my home directory.  Now, I try to open this file in three different ways:  sh somename.sh  bash somename.sh  ./somename.sh   So, I have two questions:   Why are the outputs for the above commands different though they are running the same script?   sh produces a Syntax error bash outputs the desired result ./ gives a Permission Denied error  Why is it necessary to give the script executable permission only when running the script using ./ and not necessary in the other cases?   Thanks in advance!  EDIT: The first part might be similar to the  linked one but, I did have a second question too.
27074
I am trying to find the largest file in a directory recursively. If there is a subdirectory inside of that directory the function needs to go inside that directory and check to see if the largest file is there. Once the largest file is found the output is displayed with the relative path name and the name and size of the largest file.  EX:  dude@shell2 (~...assignment/solutions) % bash maxfile.sh ~/test class/asn dude.h.gch: 9481628   This is what I have:  #!/bin/sh clear  recursiveS() {     for d in *; do         if [ -d $d ]; then             (cd $d; echo $(pwd)/$line; du -a; recursiveS;)         fi     done } recursiveS   I have been stuck for a while now. I cannot implement this by pipelining a number of existing Unix tools. Any ideas would be nice!
14187
Why does $ ls &gt; ls.out cause 'ls.out' to be included in list of names of files in current directory? Why was this chosen to be? Why not otherwise?
115449
Stupidly, I had been using a condition like this as part of a script:  if [ $(ls FOO* 2&gt; /dev/null) ] # if files named "FOO*" were downloaded  then     echo "Files found"      # ... process and email results else     echo "Not found"     # ... email warning that no files were found (against expectations) fi   That works for zero and one files named FOO*, but fails if there are more than one. From logs I found several different error messages stemming from this:  [: FOO_20131107_082920: unary operator expected [: FOO_20131108_070203: binary operator expected [: too many arguments   My question is: what is the correct way to check, in a Bash if condition, whether one or more files whose name begins with FOO exist?  GNU bash, version 4.2.25(1)-release (x86_64-pc-linux-gnu)
79632
I was recently looking at some code that confused me because it works and I didn't expect it to. The code reduces to this example  #!/bin/bash for var; do   echo "$var" done   When run with command line arguments is prints them  $ ./test a b c a b c   It is this, that is (to me) unexpected. Why does this not result in an error because var is undefined ? Is using this considered 'good practice' ?
13484
Consider the following code:  foo () {     echo $* }  bar () {     echo $@ }  foo 1 2 3 4 bar 1 2 3 4   It outputs:     1 2 3 4       1 2 3 4   I am using Ksh88, but I am interested in other common shells as well. If you happen to know any particularity for specific shells, please do mention them.  I found the follwing in the Ksh man page on Solaris:     The meaning of $* and  $@  is   identical  when  not  quoted  or  when  used  as a parameter   assignment value or as a file name. However, when used as  a   command argument, $* is equivalent to ``$1d$2d...'', where d   is the first character of the IFS variable,  whereas  $@  is   equivalent  to  $1 $2 ....   I tried modifying the IFS variable, but it doesn't modify the output. Maybe I'm doing something wrong?