So I'm trying to write a small script that loops over an array list like so  if [ $EUID != 0 ]; then    sudo "$0" "$@"    exit $? fi echo "Please enter repo password" stty -echo read PASSWORD stty echo REPOS=("repo one" "repo 2" "repo 3") for i in "${REPOS[@]}" do    sudo mount //$IPLOCATION/$i $MOUNTPATH/$i -o "username=$USERNAME,password=$PASSWORD" done   This seems to work well when the array is REPOS=("repoone" "repotwo" "repothree") But not with spaces. I tried with repo\ one and repo\\\ one but am getting no luck. I know I'm missing something stupid.
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?
13220
I am trying to feed Directory names into a for loop.  My code is as follows:  td='/Test/TopDir/' cd "$td"  for x in $(ls -d */ | cut -f1 -d'/'); do   echo x=$x done   The top directory I run this on looks like this when running an ls command:  ls -l drwxrwxrwx    4 Jason    users         4096 May  6 06:36 2014-02-02 - Jebby ( drwxrwxrwx    3 Jason    users         4096 May  6 06:09 2014-02-04 - Jebby ( drwxrwxrwx    2 root     root          4096 May  6 06:09 @eaDir -rw-r--r--    1 Jason    users      3956225 Jan 26 10:17 DSC01062.JPG -rw-r--r--    1 Jason    users      3927603 Jan 26 10:18 DSC01063.JPG   The results of my for loop is as follows:  x=2014-02-02 x=- x=Jebby x=( x=2014-02-04 x=- x=Jebby x=( x=@eaDir   As you can see the for loop is breaking the directory names into sub-pieces after each space.  In this example I only want the For Loop to execute three time with the three directories:    2014-02-02 - Jebby ( 2014-02-04 - Jebby (  @eaDir   What am I doing wrong?
87437
I'm trying to beat my head against the syntax of this. I'm getting problems with whitespaces and I can't see if there's a better way to do this.  vardir=/home/user cd $vardir for i in $(ls "$vardir") ; do timestamp="$(stat -c %Y $i)" echo "$i" echo "$timestamp"  done   Result is similar no matter where I quote and I'm not sure what I'm doing wrong:  stat: cannot stat ‘Temporary’: No such file or directory Temporary  stat: cannot stat ‘Items’: No such file or directory Items   My goal is I want to grab the timestamps off of backup directories and touch the current ones to restore the original modified dates.
122787
Is there a way to print an entire array ([key]=value) without looping over all elements?    Assume I have created an array with some elements:    declare -A array array=([a1]=1 [a2]=2 ... [b1]=bbb ... [f500]=abcdef)   I can print back the entire array with  for i in "${!array[@]}" do echo "${i}=${array[$i]}" done   However, it seems bash already knows how to get all array elements in one "go" - both keys ${!array[@]} and values ${array[@]}.    Is there a way to make bash print this info without the loop?  Edit: typeset -p array does that! However I can't remove both prefix and suffix in a single substitution:  a="$(typeset -p array)" b="${a##*(}" c="${b%% )*}"   Is there a cleaner way to get/print only the key=value portion of the output?
12024
What is the difference between find . and /home/user/* as an input to for command.? For example:  for var in $(find .) do echo "$var" done   or  for var in /home/user/* do echo "$var" done   In the first case for command breaks up the file with names containing spaces. While in the second case it does not. Why?
54030
(Note:  after some more research I have a partial answer, but I don't like having to write the actual commands against that variable differently depending on embedded spaces or not.  I'll accept better suggestions).  I like to store various work variables in bash as I am working on something.  This avoids having to type it up every time and also helps when you come back to work on it some time later (stick the assignment in a localprofile.sh file and source that later...).  I'd like to store a directory name with spaces in it.  I know how to do deal with spaces in file/directory names interactively, using either quoting or \-based escaping:  $ ls -1 /Users/myuser/Library/Application\ Support/ | tail -5 iTerm2 icdd org.videolan.vlc pip videosubscriptionsd   or  $ ls -1 "/Users/myuser/Library/Application Support/" | tail -5 iTerm2 icdd org.videolan.vlc pip videosubscriptionsd   Now I'd like to assign that directory to a bash $dn variable and that's not working so well.  Here are some various tries.  On purpose I stayed away from ~-based shell extension.  dn='/Users/myuser/Library/Application Support/' echo '' echo '' echo $dn ls -1 $dn  dn='"/Users/myuser/Library/Application Support/"' echo '' echo '' echo $dn ls -1 $dn  dn=/Users/myuser/Library/Application\ Support/ echo '' echo '' echo $dn ls -1 $dn  dn="/Users/myuser/Library/Application\ Support/" echo '' echo '' echo $dn ls -1 $dn   each one of these shows a variation on ls: /Users/myuser/Library/Application\: No such file or directory
82721
$ a='"apple","ball","cat"' $ a='['$a $ echo $a ["apple","ball","cat" $ a=$a']' $ echo $a b   I'm stumped hard by the result b while I expect to see ["apple,"ball","cat"]. What am I missing here?  This is from bash shell on Mac. Also see it on CentOS 7, while not on Fedora. Can someone please explain?
91318
In the sequence of five commands below, all depend on single-quotes to hand off possible variable substitution to the called bash shell rather than the calling shell. The calling user is xx, but the called shell will be run as user yy. The first command substitutes $HOME with the calling shell's value because the called shell is not a login shell. The second command substitutes the value of $HOME loaded by a login shell, so it is the value belonging to user yy. The third command does not rely on a $HOME value and creates a file in the guessed home directory of user yy.  Why does the fourth command fail? The intention is that it writes the same file, but relying on the $HOME variable belonging to user yy to ensure it actually does end up in her home directory. I don't understand why a login shell breaks the behaviour of a here-doc command passed in as a static single-quoted string. The failure of the fifth command verifies that this problem is not about variable substitution.  xx@host ~ $ sudo -u yy bash -c 'echo HOME=$HOME' HOME=/home/xx xx@host ~ $ sudo -iu yy bash -c 'echo HOME=$HOME' HOME=/home/yy xx@host ~ $ sudo -u yy bash -c 'cat &gt; /home/yy/test.sh &lt;&lt; "EOF" &gt; script-content &gt; EOF &gt; ' xx@host ~ $ sudo -iu yy bash -c 'cat &gt; $HOME/test.sh &lt;&lt; "EOF" &gt; script-content &gt; EOF &gt; ' bash: warning: here-document at line 0 delimited by end-of-file (wanted `EOFscript-contentEOF') xx@host ~ $ sudo -iu yy bash -c 'cat &gt; /home/yy/test.sh &lt;&lt; "EOF" &gt; script-content &gt; EOF &gt; ' bash: warning: here-document at line 0 delimited by end-of-file (wanted `EOFscript-contentEOF')   These commands were issued on a Linux Mint 18.3 Cinnamon 64-bit system, which is based on Ubuntu 16.04 (Xenial Xerus).  Update: The here-doc aspect is just clouding the issue. Here's a simplification of the problem:  $ sudo bash -c 'echo 1 &gt; echo 2' 1 2 $ sudo -i bash -c 'echo 1 &gt; echo 2' 1echo 2   Why does the first of those two commands preserve the linebreak and the second does not? sudo is common to both commands, yet seems to be escaping/filtering/interpolating differently depending on nothing but the "-i" option.
28963
I thought this would be simple - but it is proving more complex than I expected.  I want to iterate through all the files of a particular type in a directory, so I write this:  #!/bin/bash  for fname in *.zip ; do    echo current file is ${fname} done   This works as long as there is at least one matching file in the directory. However if there are no matching files, I get this:  current file is *.zip   I then tried:  #!/bin/bash  FILES=`ls *.zip` for fname in "${FILES}" ; do     echo current file is ${fname} done   While the body of the loop does not execute when there are no files, I get an error from ls:  ls: *.zip: No such file or directory   How do I write a loop which cleanly handles no matching files?
22243
I am having difficulty getting a for loop to take user input in the form of an argument to a function I created. #!/bin/bash number1=&quot;$1&quot;    #Assume user input 5 loops=&quot;$2&quot;      #Assume user input 5 if [[ ${number1} &amp;&amp; ${loops} =~ ^-?[0.00-9.99]+$ ]];then    for number2 in {1..${loops}}    do        Product=$(echo &quot;${number1} * ${number2}&quot; | bc -l)        echo &quot;${number1} * ${number2} = ${Product}&quot;        if test ${number2} -eq 7;then            { echo &quot;----------------------&quot;; echo &quot;${number2} is the best number.&quot;; echo &quot;----------------------&quot;; continue; }        elif test ${number2} -eq 11;then            { echo &quot;------------------------------&quot;; echo &quot;${number2} is pretty awesome as well.&quot;; echo &quot;------------------------------&quot;; continue; }            fi     done else    { echo &quot;Please try again with a valid numerical entry.&quot;; exit 1; } fi  This script does not run when the user inputs an integer for the variable &quot;loops&quot;, and any number for &quot;number1&quot;. number1 = 5 in this case. It returns the error:  (standard_in) 1: syntax error 5 * {1..5} = /home/$USER/For_Loop_Multiplication.sh: line 9: test: {1..5}: integer expression expected /home/$USER/For_Loop_Multiplication.sh: line 11: test: {1..5}: integer expression expected  If I instead directly input an end bound on the number of loops directly into the script like the following, and number1 = 5, it runs fine: #!/bin/bash number1=&quot;$1&quot;     #Assume user input 5 if [[ ${number1} =~ ^-?[0.00-9.99]+$ ]];then    for number2 in {1..5}    do        Product=$(echo &quot;${number1} * ${number2}&quot; | bc -l)        echo &quot;${number1} * ${number2} = ${Product}&quot;        if test ${number2} -eq 7;then            { echo &quot;----------------------&quot;; echo &quot;${number2} is the best number.&quot;; echo &quot;----------------------&quot;; continue; }        elif test ${number2} -eq 11;then            { echo &quot;------------------------------&quot;; echo &quot;${number2} is pretty awesome as well.&quot;; echo &quot;------------------------------&quot;; continue; }            fi     done else    { echo &quot;Please try again with a valid numerical entry.&quot;; exit 1; } fi  It returns the result:  5 * 1 = 5 5 * 2 = 10 5 * 3 = 15 5 * 4 = 20 5 * 5 = 25  Essentially what I think is happening is that the script seems to be placing the entire range as the value number2, which is defined as the iterator in the for loop. Since the input for the variable &quot;loops&quot; is an integer, there should be no difference between asking the user for a range and placing it in the loop, or simply setting it as a default when I write the script. However, there apparently is a difference... Any insight into solving this problem is appreciated. Thanks.
95685
If I append this:   hi=11 export hi   to the .bashrc and then I su to this user with:   su - bela   then I:   echo $hi 11   Then it's working, the "hi" variable has the value of "11". But. When I:   su -c "echo $hi" bela   the variable "hi" has no value. Why?  (running on CentOS 6)
29907
I was trying to write a shell script that will take a directory path d as an argument and recursively print a depth indented list of all files and directories in d. However, the argument d is optional and if no argument is given, a depth indented list of all files and directories​ ​in​ ​the​ ​current​ ​ directory​ will​ ​be printed. Here is my code: # the method for tree  myspace=&quot;&quot; spaceCount=0 tree(){        cd &quot;$1&quot;   for i in *; do     if [ -d &quot;$i&quot; ]; then       echo -n &quot;|&quot;          for (( j=0;j&lt;spaceCount;j++ ))        do          echo -n &quot;$myspace&quot;         done       echo &quot;--$i&quot;       spaceCount=$((spaceCount+1))        myspace=&quot;  |&quot;       tree &quot;$i&quot;     else       echo -n &quot;|&quot;       for (( j=0;j&lt;spaceCount;j++ ))        do          echo -n &quot;$myspace&quot;         done       echo &quot;--$i&quot;     fi   done   cd ../   spaceCount=$((spaceCount-1)) }   if [ &quot;$1&quot; != &quot;&quot; ]; then   file=&quot;$1&quot; fi echo &quot;.$file&quot; tree &quot;$file&quot;  But when a folder is empty, it's printing a star like this: How can I solve the problem?
119081
I am trying to output the values of array element but I am getting weird output. Please have a look at it and help me solve it. Thank you.  n=2 declare -a myarray[$n] myarray[0]=hey myarray[1]=hello myarray[2]=bye for i in ${myarray[@]} do         echo $i done   Output:  robin@robin-VirtualBox:~/lx$ sh array.sh array.sh: 2: array.sh: declare: not found array.sh: 3: array.sh: myarray[0]=hey: not found array.sh: 4: array.sh: myarray[1]=hello: not found array.sh: 5: array.sh: myarray[2]=bye: not found array.sh: 6: array.sh: Bad substitution
86008
My bash script:  #!bin/bash MY_ARRAY=("Some string" "Another string") function join { local IFS="$1"; shift; echo -e "$*"; } join "," ${MY_ARRAY[@]}   I want the output to be: Some string,Another string.  Instead, I get Some,string,Another,string.  What must I change to get the result I want?
101878
I'm writing a simple bash script, but I need it to check whether it's being run as root or not. I know there's probably a very simple way to do that, but I have no idea how.  Just to be clear: What's a simple way to write a script foo.sh, so that the command ./foo.sh outputs 0, and the command sudo ./foo.sh outputs 1?
94875
I want to print list of numbers from 1 to 100 and I use a for loop like the following:  number=100 for num in {1..$number} do   echo $num done   When I execute the command it only prints {1..100} and not the list of number from 1 to 100.
99346
I have this script that prints out a box frame with Asterisk signs, and I need to make it so that the script prints out multiple boxes under each other. How can I do it?    #!/bin/bash # echo -n "Please enter the amount of lines: " read lines echo -n "Please enter the amount of *: " read sign for((i = 1; i &lt;= $lines; i++)) do   echo -n "$i "   if [ $i -eq 1 -o $i -eq $lines ]; then   for((j = 1; j &lt;= $sign; j++))   do     echo -n "* "   done    else     echo -n "* "     for((j = 2; j &lt; $sign; j++))     do       echo -n "  "     done     echo -n "* "   fi   echo done #end