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/
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
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'
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
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.
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 \
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