I would like to embed a long command like this in a bash script:
mycommand \
--server myserver \
--filename extremely/long/file/name/that/i/would/like/to/be/able/to/break/up/if/possible \
--o开发者_如何学JAVAtherflag \
--anotherflag
with the long filename broken up.
I could do this:
# Insufficiently pretty
mycommand \
--server myserver \
--filename extremely/long/file/name/\
that/i/would/like/to/be/able/to/break/\
up/if/possible \
--otherflag \
--anotherflag \
but it breaks the flow. I would like to be able to write this:
# Doesn't work
mycommand \
--server myserver \
--filename extremely/long/file/name/\
that/i/would/like/to/be/able/to/break/\
up/if/possible \
--otherflag \
--anotherflag
but that doesn't work because it breaks up the string literal.
Is there a way to tell bash to break a string literal but ignore any leading spaces?
It's a bit of a hack, but this works:
mycommand \
--server myserver \
--filename "extremely/long/file/name/"`
`"that/i/would/like/to/be/able/to/break/"`
`"up/if/possible" \
--otherflag \
--anotherflag
Bash concatenates string literals that are adjacent, so we take advantage of that. For example, echo "hi" "there" prints hi there whereas echo "hi""there" prints hithere.
It also takes advantage of the backtick operator, and the fact that a bunch of spaces evaluates to nothing.
You can use a variable :
file=extremely/long/file/name
file+=/that/i/would/like/to/be/able/to/break
file+=/up/if/possible
mycommand\
--server myserver\
--filename $file\
--flag flag
One can also use an array variable
file=(extremely/long/file/name
/that/i/would/like/to/be/able/to/break
/up/if/possible)
IFS=''
echo mycommand\
--server myserver\
--filename "${file[*]}"\
--flag flag
Another way of writing a long string to a variable while keeping the maximum line length at bay:
printf -v fname '%s' \
'extremely/long/file/name/that/i/' \
'would/like/to/be/able/to/break/up/' \
'if/possible'
Because there are more arguments than formatting directives, %s is just repeated and we get
$ declare -p fname
declare -- fname="extremely/long/file/name/that/i/would/like/to/be/able/to/break/up/if/possible"
which an be used like
mycommand \
--server myserver \
--filename "$fname" \
--otherflag \
--anotherflag
This is extra handy when setting long variables with inherently separated contents such as CDPATH (or PATH, of course):
printf -v CDPATH '%s' \
':/Users/benjamin/here/is/a/long/path' \
':/Users/benjamin/and/here/is/another/one' \
':/Users/benjamin/and/a/third/line'
export CDPATH
as opposed to
export CDPATH=':/Users/benjamin/here/is/a/long/path:/Users/benjamin/and/here/is/another/one:/Users/benjamin/and/a/third/line'
or the clunky
export CDPATH=':/Users/benjamin/here/is/a/long/path'
CDPATH+=':/Users/benjamin/and/here/is/another/one'
CDPATH+=':/Users/benjamin/and/a/third/line'
Basically, there is nothing built into bash to do this.
A wrapper is typically more trouble than it's worth, but that said, you could try an alias or a funciton, eg. j
j(){sed -e ':a;$!N;s/ *\n *//g;ta' <<<"$1"}
echo "$(j "3 spaces
/hello
/world
/this
/is
/a
/long
/path
")"
# 3 spaces/hello/world/this/is/a/long/path
I define a short strcat function at the top of my bash script and use an inline invocation to split things up. I sometimes prefer it to using a separate variable because I can define the long literal in-line with the command invocation.
function strcat() {
local IFS=""
echo -n "$*"
}
mycommand \
--server myserver \
--filename "$(strcat \
extremely/long/file/name/ \
that/i/would/like/to/be/able/to/break/ \
up/if/possible)" \
--otherflag \
--anotherflag \
I also like this approach for when I have to enter a long CSV of values as a flag parameter because I can use it to avoid typing the comma between values:
function strjoin() {
local IFS="$1"
shift
echo -n "$*"
}
csv_args=(
foo=hello
bar=world
"this=arg has spaces in it"
)
mycommand \
--server myserver \
--csv_args "$(strjoin , "${csv_args[@]}")" \
--otherflag \
--anotherflag \
Which is equivalent to
mycommand \
--server myserver \
--csv_args "foo=hello,bar=world,this=arg has spaces in it" \
--otherflag \
--anotherflag \
加载中,请稍侯......
精彩评论