我想在bash脚本中嵌入一个这样的长命令:
mycommand \
--server myserver \
--filename extremely/long/file/name/that/i/would/like/to/be/able/to/break/up/if/possible \
--otherflag \
--anotherflag
长文件名分解。
我可以这样做:
# Insufficiently pretty
mycommand \
--server myserver \
--filename extremely/long/file/name/\
that/i/would/like/to/be/able/to/break/\
up/if/possible \
--otherflag \
--anotherflag \
但它打破了流程。我会喜欢来写这个:
# 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
但这不起作用,因为它会破坏字符串文字。
有没有办法告诉bash打破字符串文字但忽略任何前导空格?
答案 0 :(得分:50)
这是黑客的位,但这有效:
mycommand \
--server myserver \
--filename "extremely/long/file/name/"`
`"that/i/would/like/to/be/able/to/break/"`
`"up/if/possible" \
--otherflag \
--anotherflag
Bash连接相邻的字符串文字,因此我们利用它。例如,echo "hi" "there"
打印hi there
而echo "hi""there"
打印hithere
。
它还利用了反引号运算符,以及一堆空格的计算结果为空的事实。
答案 1 :(得分:41)
您可以使用变量:
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
答案 2 :(得分:2)
我在bash脚本的顶部定义了一个简短的strcat函数,并使用内联调用来分解。我有时更喜欢使用单独的变量,因为我可以使用命令调用来定义长文字。
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 \
当我必须输入一个长CSV值作为标志参数时,我也喜欢这种方法,因为我可以使用它来避免在值之间键入逗号:
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 \
相当于
mycommand \
--server myserver \
--csv_args "foo=hello,bar=world,this=arg has spaces in it" \
--otherflag \
--anotherflag \
答案 3 :(得分:2)
还可以使用数组变量
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
答案 4 :(得分:1)
基本上,bash中没有任何内容可以做到这一点
包装器通常比它的价值更麻烦,但是说,你可以尝试别名或功能,例如。 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
答案 5 :(得分:0)
将长字符串写入变量,同时保持最大行距不变的另一种方法:
printf -v fname '%s' \
'extremely/long/file/name/that/i/' \
'would/like/to/be/able/to/break/up/' \
'if/possible'
因为参数多于格式指令,所以%s
被重复了,我们得到了
$ declare -p fname
declare -- fname="extremely/long/file/name/that/i/would/like/to/be/able/to/break/up/if/possible"
使用方式
mycommand \
--server myserver \
--filename "$fname" \
--otherflag \
--anotherflag
在设置内容固有分隔的长变量(例如CDPATH
(当然是PATH
)时,这特别方便:
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
相对于
export CDPATH=':/Users/benjamin/here/is/a/long/path:/Users/benjamin/and/here/is/another/one:/Users/benjamin/and/a/third/line'
或者笨拙的
export CDPATH=':/Users/benjamin/here/is/a/long/path'
CDPATH+=':/Users/benjamin/and/here/is/another/one'
CDPATH+=':/Users/benjamin/and/a/third/line'