Làm thế nào để chỉ định một biến shell nhiều dòng?


122

Tôi đã viết một truy vấn:

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

sql cục bộ - một chuỗi rất dài. Truy vấn không được định dạng. Làm cách nào để chia một chuỗi thành nhiều dòng?


4
Những gì shellđang nói chuyện tốt ở đây? Nên batchđược bashhoặc là bạn thực sự từ Darkside?
Chris Seymour

1
nếu đây là shell / bash, bạn không nên bao quanh =bởi các khoảng trắng.
Nik O'Lai

Câu trả lời:


138

Sử dụng readvới một heredoc như hình dưới đây:

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

echo "$sql"

52
Lưu ý rằng readsẽ có mã thoát là 1 trong tình huống này; nếu điều đó quan trọng ( set -eví dụ: bạn đang chạy với ), bạn sẽ muốn thêm một || trueở cuối dòng đầu tiên.
chepner

4
set -ethoát khỏi trình bao nếu một lệnh có trạng thái thoát khác 0 "không mong đợi". Bởi "không mong đợi", ý tôi là nó chạy trong bối cảnh mà bạn không xem xét cụ thể trạng thái thoát của nó. falsechẳng hạn, tự nó sẽ thoát khỏi trình bao. false || truesẽ không, vì bạn dự đoán trạng thái thoát khác 0 bằng cách chỉ định một lệnh khác để chạy nếu lệnh đầu tiên không thành công.
chepner

1
Vấn đề với bộ -e và đọc (xem tập cuối cùng) được mô tả ở đây một cách chi tiết: mywiki.wooledge.org/BashFAQ/105
Niklas Peter

5
những gì -d ' 'làm ở đây?
hg_git

3
@hg_git Nói readđừng ngừng đọc khi gặp dòng mới.
Cyker

171

chỉ cần chèn dòng mới khi cần thiết

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

shell sẽ tìm kiếm dấu ngoặc kép đóng


7
không phải là một giải pháp tốt nếu truy vấn sql chứa dấu ngoặc kép. Bạn sẽ phải thoát khỏi chúng và nó sẽ trở nên lộn xộn.
dogbane

13
@dogbane dấu ngoặc kép hiếm khi xuất hiện trong hầu hết các phương ngữ SQL, vì vậy trong thực tế, điều này rất rõ ràng.
Iain Samuel McLean Elder,

4
Sau đó, quấn chuỗi trong dấu ngoặc kép.
tripleee

Không chắc chắn tại sao bạn muốn hoặc cần ngắt dòng hàng đầu. Đối với ứng dụng của tôi, tôi không vì vậy tôi chỉ mới bắt đầu vớisql="SELECT c2, c2
bhfailor

1
Thật buồn cười khi điều đó có vẻ quá dễ dàng thành sự thật. FYI, để thêm DQ, chỉ cần tạo một biến DQ = '\ "' và sau đó tham chiếu nó trong câu lệnh với $ {DQ}.
Timothy C. Quinn

69

Tôi muốn đưa ra một câu trả lời bổ sung, trong khi những câu khác sẽ đủ trong hầu hết các trường hợp.

Tôi muốn viết một chuỗi trên nhiều dòng, nhưng nội dung của nó cần phải là một dòng.

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

Tôi xin lỗi nếu điều này hơi lạc đề (tôi không cần điều này cho SQL). Tuy nhiên, bài đăng này xuất hiện trong số các kết quả đầu tiên khi tìm kiếm các biến shell nhiều dòng và một câu trả lời bổ sung có vẻ phù hợp.


1
Ngay cả khi không có \ ', nội dung của tôi vẫn xuất hiện trên một dòng.
papiro

12
@papiro, hãy thử echo "$sql"thay vì echo $sql.
Michael Mol

@MichaelMol - Khoảng hai thập kỷ sau lần cài đặt Linux đầu tiên của tôi và tôi vẫn học được nhiều điều mới. Cảm ơn vì "thủ thuật" này.
Seth

6

Nhờ câu trả lời của dimo414 cho một câu hỏi tương tự , điều này cho thấy giải pháp tuyệt vời của anh ấy hoạt động như thế nào và cho thấy rằng bạn cũng có thể có dấu ngoặc kép và biến trong văn bản một cách dễ dàng:

đầu ra ví dụ

$ ./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

readkhông xuất biến (đó là một điều tốt trong hầu hết thời gian). Đây là một giải pháp thay thế có thể được xuất trong một lệnh, có thể bảo toàn hoặc loại bỏ nguồn cấp dữ liệu dòng và cho phép trộn các kiểu trích dẫn khi cần thiết. Hoạt động cho bash và zsh.

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

Tôi thừa nhận nhu cầu trích dẫn làm cho điều này trở nên xấu xí đối với SQL, nhưng nó trả lời câu hỏi (được diễn đạt chung hơn) trong tiêu đề.

Tôi sử dụng nó như thế này

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')

trong một tệp có nguồn từ cả của tôi .bashrc.zshrc.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.