Retrieving multiple arguments for a single option using getopts in Bash
You can use the same option multiple times and add all values to an array.
For the very specific original question here, Ryan's mkdir -p
solution is obviously the best.
However, for the more general question of getting multiple values from the same option with getopts, here it is:
#!/bin/bashwhile getopts "m:" opt; do case $opt in m) multi+=("$OPTARG");; #... esacdoneshift $((OPTIND -1))echo "The first value of the array 'multi' is '$multi'"echo "The whole list of values is '${multi[@]}'"echo "Or:"for val in "${multi[@]}"; do echo " - $val"done
The output would be:
$ /tmp/tThe first value of the array 'multi' is ''The whole list of values is ''Or:$ /tmp/t -m "one arg with spaces"The first value of the array 'multi' is 'one arg with spaces'The whole list of values is 'one arg with spaces'Or: - one arg with spaces$ /tmp/t -m one -m "second argument" -m threeThe first value of the array 'multi' is 'one'The whole list of values is 'one second argument three'Or: - one - second argument - three
I know this question is old, but I wanted to throw this answer on here in case someone comes looking for an answer.
Shells like BASH support making directories recursively like this already, so a script isn't really needed. For instance, the original poster wanted something like:
$ foo.sh -i test -d directory -s subdirectory -s subdirectory2 -f file1 file2 file3/test/directory/subdirectory/file1/test/directory/subdirectory/file2/test/directory/subdirectory/file3/test/directory/subdirectory2/file1/test/directory/subdirectory2/file2/test/directory/subdirectory2/file3
This is easily done with this command line:
pong:~/tmp[10] rmclean$ mkdir -pv test/directory/{subdirectory,subdirectory2}/{file1,file2,file3}mkdir: created directory ‘test’mkdir: created directory ‘test/directory’mkdir: created directory ‘test/directory/subdirectory’mkdir: created directory ‘test/directory/subdirectory/file1’mkdir: created directory ‘test/directory/subdirectory/file2’mkdir: created directory ‘test/directory/subdirectory/file3’mkdir: created directory ‘test/directory/subdirectory2’mkdir: created directory ‘test/directory/subdirectory2/file1’mkdir: created directory ‘test/directory/subdirectory2/file2’mkdir: created directory ‘test/directory/subdirectory2/file3’
Or even a bit shorter:
pong:~/tmp[12] rmclean$ mkdir -pv test/directory/{subdirectory,subdirectory2}/file{1,2,3}mkdir: created directory ‘test’mkdir: created directory ‘test/directory’mkdir: created directory ‘test/directory/subdirectory’mkdir: created directory ‘test/directory/subdirectory/file1’mkdir: created directory ‘test/directory/subdirectory/file2’mkdir: created directory ‘test/directory/subdirectory/file3’mkdir: created directory ‘test/directory/subdirectory2’mkdir: created directory ‘test/directory/subdirectory2/file1’mkdir: created directory ‘test/directory/subdirectory2/file2’mkdir: created directory ‘test/directory/subdirectory2/file3’
Or shorter, with more conformity:
pong:~/tmp[14] rmclean$ mkdir -pv test/directory/subdirectory{1,2}/file{1,2,3}mkdir: created directory ‘test’mkdir: created directory ‘test/directory’mkdir: created directory ‘test/directory/subdirectory1’mkdir: created directory ‘test/directory/subdirectory1/file1’mkdir: created directory ‘test/directory/subdirectory1/file2’mkdir: created directory ‘test/directory/subdirectory1/file3’mkdir: created directory ‘test/directory/subdirectory2’mkdir: created directory ‘test/directory/subdirectory2/file1’mkdir: created directory ‘test/directory/subdirectory2/file2’mkdir: created directory ‘test/directory/subdirectory2/file3’
Or lastly, using sequences:
pong:~/tmp[16] rmclean$ mkdir -pv test/directory/subdirectory{1..2}/file{1..3}mkdir: created directory ‘test’mkdir: created directory ‘test/directory’mkdir: created directory ‘test/directory/subdirectory1’mkdir: created directory ‘test/directory/subdirectory1/file1’mkdir: created directory ‘test/directory/subdirectory1/file2’mkdir: created directory ‘test/directory/subdirectory1/file3’mkdir: created directory ‘test/directory/subdirectory2’mkdir: created directory ‘test/directory/subdirectory2/file1’mkdir: created directory ‘test/directory/subdirectory2/file2’mkdir: created directory ‘test/directory/subdirectory2/file3’
getopts options can only take zero or one argument. You might want to change your interface to remove the -f option, and just iterate over the remaining non-option arguments
usage: foo.sh -i end -d dir -s subdir file [...]
So,
while getopts ":i:d:s:" opt; do case "$opt" in i) initial=$OPTARG ;; d) dir=$OPTARG ;; s) sub=$OPTARG ;; esacdoneshift $(( OPTIND - 1 ))path="/$initial/$dir/$sub"mkdir -p "$path"for file in "$@"; do touch "$path/$file"done