I need help with getopts
.
I created a Bash script which looks like this when run:
$ foo.sh -i env -d directory -s subdirectory -f file
It works correctly when handling one argument from each flag. But when I invoke several arguments from each flag I am not sure how to pull the multiple variable information out of the variables in getopts
.
while getopts ":i:d:s:f:" opt do case $opt in i ) initial=$OPTARG;; d ) dir=$OPTARG;; s ) sub=$OPTARG;; f ) files=$OPTARG;; esac done
After grabbing the options I then want to build directory structures from the variables
foo.sh -i test -d directory -s subdirectory -s subdirectory2 -f file1 file2 file3
Then the directory structure would be
/test/directory/subdirectory/file1 /test/directory/subdirectory/file2 /test/directory/subdirectory/file3 /test/directory/subdirectory2/file1 /test/directory/subdirectory2/file2 /test/directory/subdirectory2/file3
Any ideas?
On Unix-like operating systems, getopts is a builtin command of the Bash shell. It parses command options and arguments, such as those passed to a shell script. How it works. Specifying the optstring. Verbose error checking.
The main differences between getopts and getopt are as follows: getopt does not handle empty flag arguments well; getopts does. getopts is included in the Bourne shell and Bash; getopt needs to be installed separately. getopt allows for the parsing of long options ( --help instead of -h ); getopts does not.
According to man getopts , OPTIND is the index of the next argument to be processed (starting index is 1).
Description. The getopts command is a Korn/POSIX Shell built-in command that retrieves options and option-arguments from a list of parameters. An option begins with a + (plus sign) or a - (minus sign) followed by a character. An option that does not begin with either a + or a - ends the OptionString.
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/bash while getopts "m:" opt; do case $opt in m) multi+=("$OPTARG");; #... esac done shift $((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/t The 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 three The 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’
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With