Issue
I need the ability to back up and then later use all input args to a bash program, but can't figure it out. Here is my attempt:
back_up_all_input_args.sh:
#!/usr/bin/env bash
all_args1="$@"
all_args2="$(printf "%q " "$@")"
# Simulate parsing the input args here
# - see: https://stackoverflow.com/a/14203146/4561887
shift # remove 1st arg
shift # remove 2nd arg
echo "$@"
echo "$all_args1"
echo "$all_args2"
# Do another program call with all input args here
# rg "$all_args1" # FAILS
# rg "$all_args2" # FAILS
Sample run and output:
$ ./backup_all_input_args.sh arg1 "arg 2" "arg 3" arg 3 arg1 arg 2 arg 3 arg1 arg\ 2 arg\ 3
My first approach was to back up the arguments with all_args1="$@"
. This fails because I lose the quotes and get arg1 arg 2 arg 3
. My 2nd approach was to back up the arguments with all_args2="$(printf "%q " "$@")"
. This fails because again, I lose the quotes, and it just so happens the first argument doesn't just need to be stuck together with the backslash like a file path, but rather, it is a regular expression argument, so it needs to remain truly unmodified. This, therefore, is not equal to the original input: arg1 arg\ 2 arg\ 3
.
References I've already studied to get this far
- How to keep quotes in Bash arguments?
- How can I preserve quotes in printing a bash script's arguments
- How do I parse command line arguments in Bash?
Bash demo
Update: this Q&A, now that I have an answer, contributed to these bash demos I just wrote:
Solution
Add parentheses and store them in an array. This will preserve each of the arguments as separate words and avoids all the backslash escaping complexities.
all_args=("$@")
You can then pass the arguments to another command:
cmd "${all_args[@]}"
Or print them out:
printf '[%s]\n' "${all_args[@]}"
Or assign them to another array:
args_copy=("${all_args[@]}")
You can also use set
restore the script's original $1
, $2
, etc., arguments:
set -- "${all_args[@]}"
Answered By - John Kugelman