Skip to main content
added 7 characters in body
Source Link
cuonglm
  • 158.2k
  • 41
  • 342
  • 420
`"$@"` expands to the script arguments, quoting them as needed 

No, this is not what happens. Calling a program takes a list of arguments, each argument being a string. When you run the shell program ./test.sh foo "bar baz", this builds a call with three arguments: ./test.sh, foo, and bar baz. (The zeroth argument is the program name; this allows programs to know under what name they are called.) Quoting is a feature of the shell, not a feature of program calls. The shell builds this list when it makes the call.

"$@" directly copies the list of arguments passed to the script or function to the list of arguments in the call where it's used. There is no quoting involved since there is no shell parsing done on those lists.

In cat <<< "$@", you're using "$@" in a context where a single string is required. The <<< operator` requires a string, not a list of strings. In this context, bash takes the elements of the list and joins them with a space in between.

For script debugging, if you run set -x (set +x to turn off), that activates a trace mode where each command is printed before is executed. In bash, that trace has quotes which make it possible to paste the command back into a shell (this isn't true of every sh implementation).

If you have a string and you want to turn it into shell source syntax that parses back into the original string, you can surround it with single quotes, and replace every single quote inside the string with '\''.

for x do printf %s "'${x//\'/\'\\\'\'}' " done echo 

The string replacement syntax is kshksh93/bash/zsh/mksh-specific. In plain sh, you need to loop over the string.

for raw do quoted= while case "$raw" in *\'*) true;; *) false;; esac; do quoted="$quoted'\\''${raw%%\'*}" raw="${raw#*\'}" done printf %s "'$quoted$raw' " done echo 
`"$@"` expands to the script arguments, quoting them as needed 

No, this is not what happens. Calling a program takes a list of arguments, each argument being a string. When you run the shell program ./test.sh foo "bar baz", this builds a call with three arguments: ./test.sh, foo, and bar baz. (The zeroth argument is the program name; this allows programs to know under what name they are called.) Quoting is a feature of the shell, not a feature of program calls. The shell builds this list when it makes the call.

"$@" directly copies the list of arguments passed to the script or function to the list of arguments in the call where it's used. There is no quoting involved since there is no shell parsing done on those lists.

In cat <<< "$@", you're using "$@" in a context where a single string is required. The <<< operator` requires a string, not a list of strings. In this context, bash takes the elements of the list and joins them with a space in between.

For script debugging, if you run set -x (set +x to turn off), that activates a trace mode where each command is printed before is executed. In bash, that trace has quotes which make it possible to paste the command back into a shell (this isn't true of every sh implementation).

If you have a string and you want to turn it into shell source syntax that parses back into the original string, you can surround it with single quotes, and replace every single quote inside the string with '\''.

for x do printf %s "'${x//\'/\'\\\'\'}' " done echo 

The string replacement syntax is ksh/bash/zsh-specific. In plain sh, you need to loop over the string.

for raw do quoted= while case "$raw" in *\'*) true;; *) false;; esac; do quoted="$quoted'\\''${raw%%\'*}" raw="${raw#*\'}" done printf %s "'$quoted$raw' " done echo 
`"$@"` expands to the script arguments, quoting them as needed 

No, this is not what happens. Calling a program takes a list of arguments, each argument being a string. When you run the shell program ./test.sh foo "bar baz", this builds a call with three arguments: ./test.sh, foo, and bar baz. (The zeroth argument is the program name; this allows programs to know under what name they are called.) Quoting is a feature of the shell, not a feature of program calls. The shell builds this list when it makes the call.

"$@" directly copies the list of arguments passed to the script or function to the list of arguments in the call where it's used. There is no quoting involved since there is no shell parsing done on those lists.

In cat <<< "$@", you're using "$@" in a context where a single string is required. The <<< operator` requires a string, not a list of strings. In this context, bash takes the elements of the list and joins them with a space in between.

For script debugging, if you run set -x (set +x to turn off), that activates a trace mode where each command is printed before is executed. In bash, that trace has quotes which make it possible to paste the command back into a shell (this isn't true of every sh implementation).

If you have a string and you want to turn it into shell source syntax that parses back into the original string, you can surround it with single quotes, and replace every single quote inside the string with '\''.

for x do printf %s "'${x//\'/\'\\\'\'}' " done echo 

The string replacement syntax is ksh93/bash/zsh/mksh-specific. In plain sh, you need to loop over the string.

for raw do quoted= while case "$raw" in *\'*) true;; *) false;; esac; do quoted="$quoted'\\''${raw%%\'*}" raw="${raw#*\'}" done printf %s "'$quoted$raw' " done echo 
Source Link
Gilles 'SO- stop being evil'
  • 865.9k
  • 205
  • 1.8k
  • 2.3k

`"$@"` expands to the script arguments, quoting them as needed 

No, this is not what happens. Calling a program takes a list of arguments, each argument being a string. When you run the shell program ./test.sh foo "bar baz", this builds a call with three arguments: ./test.sh, foo, and bar baz. (The zeroth argument is the program name; this allows programs to know under what name they are called.) Quoting is a feature of the shell, not a feature of program calls. The shell builds this list when it makes the call.

"$@" directly copies the list of arguments passed to the script or function to the list of arguments in the call where it's used. There is no quoting involved since there is no shell parsing done on those lists.

In cat <<< "$@", you're using "$@" in a context where a single string is required. The <<< operator` requires a string, not a list of strings. In this context, bash takes the elements of the list and joins them with a space in between.

For script debugging, if you run set -x (set +x to turn off), that activates a trace mode where each command is printed before is executed. In bash, that trace has quotes which make it possible to paste the command back into a shell (this isn't true of every sh implementation).

If you have a string and you want to turn it into shell source syntax that parses back into the original string, you can surround it with single quotes, and replace every single quote inside the string with '\''.

for x do printf %s "'${x//\'/\'\\\'\'}' " done echo 

The string replacement syntax is ksh/bash/zsh-specific. In plain sh, you need to loop over the string.

for raw do quoted= while case "$raw" in *\'*) true;; *) false;; esac; do quoted="$quoted'\\''${raw%%\'*}" raw="${raw#*\'}" done printf %s "'$quoted$raw' " done echo