如何指定多行外壳变量?


122

我写了一个查询:

function print_ui_hosts
{
local sql = "select ........."
print_sql "$ sql"
}

本地sql-一个非常长的字符串。查询未格式化。如何将字符串分成多行?


4
这里shell有什么好话的?应该batchbash或者是你真正从阴暗面?
克里斯·西摩

1
如果是shell / bash,则不=要用空格包围。
Nik O'Lai 2013年

Answers:


138

read与heredoc一起使用,如下所示:

read -d '' sql << EOF
select c1, c2 from foo
where c1='something'
EOF

echo "$sql"

52
请注意,read在这种情况下,退出代码为1;如果那很重要(set -e例如,您正在使用进行运行),则需要|| true在第一行的末尾添加一个。
13

4
set -e如果命令具有“意外”非零退出状态,则退出Shell。所谓“意外”,是指它在您没有专门查看其退出状态的情况下运行。false例如,它本身会退出外壳。false || true不会,因为您要通过指定另一个命令(如果第一个失败)来运行来预测非零退出状态。
chepner

1
set -e和read的问题(请参阅上一练习)在此处详细描述:mywiki.wooledge.org/BashFAQ/105
Niklas Peter

5
是什么-d ' '在这里做?
hg_git 2016年

3
@hg_git告诉read遇到换行符时不要停止阅读。
Cyker '16

170

只需在必要时插入新行

sql="
SELECT c1, c2
from Table1, Table2
where ...
"

外壳将寻找结束引号


7
如果sql查询包含双引号,则不是一个好的解决方案。您将不得不逃脱它们,并且会变得凌乱。
dogbane 2013年

13
@dogbane双引号在大多数SQL方言中很少出现,因此实际上这是干净的。
伊恩·塞缪尔·麦克莱恩

4
然后将字符串用单引号引起来。
三胞胎

不确定为什么要或需要换行。对于我的应用程序,我没有,所以我只是从sql="SELECT c2, c2
bhfailor

1
有趣的是,这似乎很容易成为现实。仅供参考,以补充DQ,只需创建一个变量DQ =“\”“,然后用$ {} DQ引用它的声明。
蒂莫西C.奎因

69

我想再给出一个答案,而在大多数情况下,其他答案就足够了。

我想在多行上写一个字符串,但是它的内容必须是单行。

sql="                       \
SELECT c1, c2               \
from Table1, ${TABLE2}      \
where ...                   \
"

如果这有点偏离主题,我感到很抱歉(SQL不需要此功能)。但是,此帖子出现在搜索多行外壳变量时的第一个结果中,并且一个附加的答案似乎很合适。


1
即使没有\,我的内容也会显示在一行上。
papiro 2016年

12
@papiro,尝试echo "$sql"代替echo $sql
Michael Mol

@MichaelMol-在我第一次安装Linux之后约二十年,我仍然学到新知识。感谢您的“技巧”。
赛斯,

6

多亏了dimo414对类似问题的回答,这说明了他的出色解决方案是如何工作的,并表明您也可以轻松地在文本中添加引号和变量:

示例输出

$ ./test.sh

The text from the example function is:
  Welcome dev: Would you "like" to know how many 'files' there are in /tmp?

  There are "      38" files in /tmp, according to the "wc" command

test.sh

#!/bin/bash

function text1()
{
  COUNT=$(\ls /tmp | wc -l)
cat <<EOF

  $1 Would you "like" to know how many 'files' there are in /tmp?

  There are "$COUNT" files in /tmp, according to the "wc" command

EOF
}

function main()
{
  OUT=$(text1 "Welcome dev:")
  echo "The text from the example function is: $OUT"
}

main

5

read不导出变量(大多数情况下这是一件好事)。这是一种替代方法,可以在一个命令中导出,可以保留或放弃换行符,并可以根据需要混合使用引号样式。适用于bash和zsh。

oneLine=$(printf %s \
    a   \
    " b "   \
    $'\tc\t'    \
    'd '    \
)
multiLine=$(printf '%s\n' \
    a   \
    " b "   \
    $'\tc\t'    \
    'd '    \
)

我承认对SQL来说,引用很麻烦,但是它回答了标题中的(更普遍表达的)问题。

我这样用

export LS_COLORS=$(printf %s    \
    ':*rc=36:*.ini=36:*.inf=36:*.cfg=36:*~=33:*.bak=33:*$=33'   \
    ...
    ':bd=40;33;1:cd=40;33;1:or=1;31:mi=31:ex=00')

在来自my .bashrc和的文件中.zshrc

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.