简体   繁体   中英

Bash quote behavior and sed

I wrote a short bash script that is supposed to strip the leading tabs/spaces from a string:

#!/bin/bash
RGX='s/^[ \t]*//'
SED="sed '$RGX'"
echo "       string" | $SED

It works from the command line, but the script gets this error:

sed: -e expression #1, char 1: unknown command: `''

My guess is that something is wrong with the quotes, but I'm not sure what.

It does. Try:

#!/bin/bash
RGX='s/^[ \t]*//'
#SED='$RGX'
echo "       string" | sed "$RGX"

This works.

The issue you have is with quotes and spaces. Double quoted strings are passed as single arguments.

Add set -x to your script. You'll see that variables within a single-quote mark are not expanded.

Putting commands into variables and getting them back out intact is hard, because quoting doesn't work the way you expect (see BashFAQ #050, "I'm trying to put a command in a variable, but the complex cases always fail!" ). There are several ways to deal with this:

1) Don't do it unless you really need to. Seriously, unless you have a good reason to put your command in a variable first, just execute it and don't deal with this messiness.

2) Don't use eval unless you really really really need to. eval has a well-deserved reputation as a source of nasty and obscure bugs. They can be avoided if you understand them well enough and take the necessary precautions to avert them, but this should really be a last resort.

3) If you really must define a command at one point and use it later, either define it as a function or an array. Here's how to do it with a function:

RGX='s/^[ \t]*//'
SEDCMD() { sed "$RGX"; }
echo "       string" | SEDCMD

Here's the array version:

RGX='s/^[ \t]*//'
SEDCMD=(sed "$RGX")
echo "       string" | "${SEDCMD[@]}"

The idiom "${SEDCMD[@]}" lets you expand an array, keeping each element a separate word, without any of the problems you're having.

+To expand on my comment above:

#!/bin/bash
RGX='s/^[[:space:]]+//'
SED="sed -r '$RGX'"
eval "printf \" \tstring\n\" | $SED"

Note that this also makes your regex an extended one, for no particular reason. :-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM