Re: eval a=b\ c
On Wed, May 27, 2015 at 12:59:53AM -0700, Dave Yost wrote: > OK, I can make it to work in bash if I say > echodo a=b\\ c > but then zsh tries to execute c. Can’t win. > > The problem is: how do I write this function so that it can be invoked > identically in zsh and bash with identical results of setting a variable to a > value with a space in it? dualbus@hp ~ % for sh in bash zsh; do "$sh" -c 'echodo(){ echo "$*"; eval "$@"; }; echodo a=b\\ c; echo "$a"'; done a=b\ c b c a=b\ c b c -- Eduardo Bustamante https://dualbus.me/
Re: eval a=b\ c
OK, I can make it to work in bash if I say echodo a=b\\ c but then zsh tries to execute c. Can’t win. The problem is: how do I write this function so that it can be invoked identically in zsh and bash with identical results of setting a variable to a value with a space in it? > On 2015-05-26, at 1:04 AM, Andreas Schwab wrote: > > d...@yost.com writes: > >>eval$@ > > You are expanding a shell parameter unquoted. Never do that unless you > know what you are doing. > > eval "$@" > > Andreas. > > -- > Andreas Schwab, SUSE Labs, sch...@suse.de > GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 > "And now for something completely different." On 2015-05-25, at 6:12 PM, Dennis Williamson wrote: > I'm trying to put a command in a variable, but the complex cases always fail! > : http://mywiki.wooledge.org/BashFAQ/050 > > Eval command and security issues : http://mywiki.wooledge.org/BashFAQ/048 > > On Mon, May 25, 2015 at 2:33 PM, wrote: > Configuration Information [Automatically generated, do not change]: > Machine: x86_64 > OS: linux-gnu > Compiler: gcc > Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' > -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-unknown-linux-gnu' > -DCONF_VENDOR='unknown' -DLOCALEDIR='/usr/local/bash/4.3.39/share/locale' > -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I../bash-4.3 > -I../bash-4.3/include -I../bash-4.3/lib -g -O2 > uname output: Linux s6.millcomputing.com 2.6.32-504.16.2.el6.x86_64 #1 SMP > Wed Apr 22 06:48:29 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux > Machine Type: x86_64-unknown-linux-gnu > > Bash Version: 4.3 > Patch Level: 39 > Release Status: release > > Description: > > # Echo the arguments, then execute them as a command. > function echodo() { > if [[ -n $ZSH_VERSION ]] ; then > echo "[ ${(q)@} ]" > eval${(q)@} > else > echo "[ $@ ]" > eval$@ > fi > } > echodo echo b\ c > echodo a=b\ c > echo $a > > The result in zsh is: > $ echodo echo b\ c > [ echo b\ c ] > b c > $ echodo a=b\ c > [ a=b\ c ] > $ echo $a > b c > $ > > Bash gets an error: > $ echodo echo b\ c > [ echo b c ] > b c > $ echodo a=b\ c > [ a=b c ] > bash: c: command not found > $ echo $a > > $ > > I can't find a way to implement echodo in bash. Apparently this is because > bash is unable to expand a variable with quoting intact, as zsh can do with > its (q) expansion flag. > > Bash behaves differently in this case:: > > $ echodo export a=b\ c > [ export a=b c ] > $ echo $a > b > $ > > > Repeat-By: > > > > Fix: > > > > > -- > Visit serverfault.com to get your system administration questions answered. >
Re: eval a=b\ c
On Mon, May 25, 2015 at 12:33:53PM -0700, d...@yost.com wrote: > # Echo the arguments, then execute them as a command. > I can't find a way to implement echodo in bash. set -x your code set +x
Re: eval a=b\ c
d...@yost.com writes: > eval$@ You are expanding a shell parameter unquoted. Never do that unless you know what you are doing. eval "$@" Andreas. -- Andreas Schwab, SUSE Labs, sch...@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different."
Re: eval a=b\ c
Dennis Williamson wrote: I'm trying to put a command in a variable, but the complex cases always fail! : http://mywiki.wooledge.org/BashFAQ/050 Eval command and security issues : http://mywiki.wooledge.org/BashFAQ/048 Dunno, but I see nothing on that page about using printf -v "%q" or using single quotes inside of doubles... in his first example: # This code is evil and should never be used! fifth() { _fifth_array=$1 eval echo "\"The fifth element is \${$_fifth_array[4]}\"" # DANGER! } a=(zero one two three four five) fifth a --- Had been written: fifth() { printf -v _fifth_array "%q" "$1" eval echo "'The fifth element is ${ echo "${_fifth_array[4]}" }'" } --- Then his arbitrary arg function throws an error: fifth 'x}'; date; -bash: 'The fifth element is ${ echo "${_fifth_array[4]}" }': bad substitution However, if someone takes user input... it needs to be way sterilized -- i.e. if expecting a single char -- only accept a single char. if expecting a number... ${i//[^0-9]/} : i=948392480 Ishtar:law> echo ${i//[^0-9]/} 948392480 i=9'\010'3{92}480 echo ${i//[^0-9]/} 9010392480 --- But I think a difference between greg's thinking and mine is that I tend to write scripts to help me do things on my system. If someone else wants to use my scripts -- and then use them to try to break into their own systemum... *oh well*... ;-)
Re: eval a=b\ c
I'm trying to put a command in a variable, but the complex cases always fail! : http://mywiki.wooledge.org/BashFAQ/050 Eval command and security issues : http://mywiki.wooledge.org/BashFAQ/048 On Mon, May 25, 2015 at 2:33 PM, wrote: > Configuration Information [Automatically generated, do not change]: > Machine: x86_64 > OS: linux-gnu > Compiler: gcc > Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' > -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-unknown-linux-gnu' > -DCONF_VENDOR='unknown' -DLOCALEDIR='/usr/local/bash/4.3.39/share/locale' > -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I../bash-4.3 > -I../bash-4.3/include -I../bash-4.3/lib -g -O2 > uname output: Linux s6.millcomputing.com 2.6.32-504.16.2.el6.x86_64 #1 > SMP Wed Apr 22 06:48:29 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux > Machine Type: x86_64-unknown-linux-gnu > > Bash Version: 4.3 > Patch Level: 39 > Release Status: release > > Description: > > # Echo the arguments, then execute them as a command. > function echodo() { > if [[ -n $ZSH_VERSION ]] ; then > echo "[ ${(q)@} ]" > eval${(q)@} > else > echo "[ $@ ]" > eval$@ > fi > } > echodo echo b\ c > echodo a=b\ c > echo $a > > The result in zsh is: > $ echodo echo b\ c > [ echo b\ c ] > b c > $ echodo a=b\ c > [ a=b\ c ] > $ echo $a > b c > $ > > Bash gets an error: > $ echodo echo b\ c > [ echo b c ] > b c > $ echodo a=b\ c > [ a=b c ] > bash: c: command not found > $ echo $a > > $ > > I can't find a way to implement echodo in bash. Apparently this is because > bash is unable to expand a variable with quoting intact, as zsh can do with > its (q) expansion flag. > > Bash behaves differently in this case:: > > $ echodo export a=b\ c > [ export a=b c ] > $ echo $a > b > $ > > > Repeat-By: > > > > Fix: > > -- Visit serverfault.com to get your system administration questions answered.
Re: eval a=b\ c
d...@yost.com wrote: Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-unknown-linux-gnu' -DCONF_VENDOR='unknown' -DLOCALEDIR='/usr/local/bash/4.3.39/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I../bash-4.3 -I../bash-4.3/include -I../bash-4.3/lib -g -O2 uname output: Linux s6.millcomputing.com 2.6.32-504.16.2.el6.x86_64 #1 SMP Wed Apr 22 06:48:29 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux Machine Type: x86_64-unknown-linux-gnu Bash Version: 4.3 Patch Level: 39 Release Status: release Description: # Echo the arguments, then execute them as a command. function echodo() { if [[ -n $ZSH_VERSION ]] ; then echo "[ ${(q)@} ]" eval${(q)@} else echo "[ $@ ]" eval$@ fi } echodo echo b\ c echodo a=b\ c echo $a The result in zsh is: $ echodo echo b\ c [ echo b\ c ] b c $ echodo a=b\ c [ a=b\ c ] $ echo $a b c $ Bash gets an error: $ echodo echo b\ c You need to put \\ there: echodo () { echo "[ $a ]" eval $@ } Ishtar:law> echodo a=b\\ c [ b\ c ]< echo $a b c Your first BackSlash was removed on the calling command line, that means (as the 'echo' shows, that the BS is no longer there. so you are telling eval to evaluate both expressions a=b & 'c' But if you use \\, one goes away on call, and the other is till there for eval. [ echo b c ] b c $ echodo a=b\ c [ a=b c ] bash: c: command not found $ echo $a $ I can't find a way to implement echodo in bash. Apparently this is because bash is unable to expand a variable with quoting intact, as zsh can do with its (q) expansion flag. Bash behaves differently in this case:: echodo export a=b\\ c [ export a=b\ c ] Ishtar:law> echo $a b c --- Same ... You are using 2 levels of dequoting, so you need 2 BS's. Make sense? Alternatively, you can pass 1 BS if you quote the initial expression: echodo 'export a=b\ c' [ export a=b\ c ] Ishtar:law> typeset -p a declare -x a="b c" (I used typeset (or declare) -p to also show the "-x" (export) flag was set). Alternatively you could also do it this way: echodo () { printf -v v -- "%q " "$@" echo "$v"; eval $v } Ishtar:law> echodo export a=b\ c export a=b\ c Ishtar:law> typeset -p a declare -x a="b c" You can do what you want in bash, you just have to be clear about what you are telling it (same goes for most any program! ;-))
Re: eval a=b\ c
On 25/05/15 20:33, d...@yost.com wrote: > if [[ -n $ZSH_VERSION ]] ; then > echo "[ ${(q)@} ]" > eval${(q)@} > else > echo "[ $@ ]" > eval$@ > fi I believe the bash equivalent here would be something along the lines of: quoted=$(printf '%q ' "$@") quoted=${quoted% } echo "[ $quoted ]" eval "$quoted" You mention that bash is "unable to expand a variable with quoting intact", but nor is zsh. Zsh and bash can only quote a variable so that it won't break when used as an argument, but there is no way to retrieve the original quoting once it has been parsed by the shell. Usually if you want to pass around executable bash code you should do it in one already properly-quoted string that gets passed around in a single argument. Quoting the string (as we're having to do as part of "echodo") might be better off as another function. You already have zsh and bash cases, and I've seen some 'clever' shell quoting tricks at http://www.etalabs.net/sh_tricks.html which should work across pretty much every bourne-like shell under the sun.
eval a=b\ c
Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-unknown-linux-gnu' -DCONF_VENDOR='unknown' -DLOCALEDIR='/usr/local/bash/4.3.39/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I../bash-4.3 -I../bash-4.3/include -I../bash-4.3/lib -g -O2 uname output: Linux s6.millcomputing.com 2.6.32-504.16.2.el6.x86_64 #1 SMP Wed Apr 22 06:48:29 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux Machine Type: x86_64-unknown-linux-gnu Bash Version: 4.3 Patch Level: 39 Release Status: release Description: # Echo the arguments, then execute them as a command. function echodo() { if [[ -n $ZSH_VERSION ]] ; then echo "[ ${(q)@} ]" eval${(q)@} else echo "[ $@ ]" eval$@ fi } echodo echo b\ c echodo a=b\ c echo $a The result in zsh is: $ echodo echo b\ c [ echo b\ c ] b c $ echodo a=b\ c [ a=b\ c ] $ echo $a b c $ Bash gets an error: $ echodo echo b\ c [ echo b c ] b c $ echodo a=b\ c [ a=b c ] bash: c: command not found $ echo $a $ I can't find a way to implement echodo in bash. Apparently this is because bash is unable to expand a variable with quoting intact, as zsh can do with its (q) expansion flag. Bash behaves differently in this case:: $ echodo export a=b\ c [ export a=b c ] $ echo $a b $ Repeat-By: Fix: