2011-01-12 10 views
18

Có thể chuyển tài liệu ở đây dưới dạng đối số hàm bash và trong hàm có tham số được giữ nguyên dưới dạng biến nhiều hàng không?Ở đây tài liệu là đối số cho hàm bash

Something dọc theo dòng sau đây:

function printArgs { 
echo arg1="$1" 
echo -n arg2= 
cat <<EOF 
$2 
EOF 
} 

printArgs 17 <<EOF 
18 
19 
EOF 

hoặc có thể:

printArgs 17 $(cat <<EOF 
18 
19 
EOF) 

Tôi có một tài liệu ở đây mà tôi muốn nuôi để ssh như các lệnh để thực hiện, và phiên ssh là được gọi từ một hàm bash.

Trả lời

5

Nếu bạn không sử dụng cái gì đó sẽ hấp thụ tiêu chuẩn đầu vào, sau đó bạn sẽ phải cung cấp một cái gì đó mà nó:

$ foo() { while read -r line; do var+=$line; done; } 
$ foo <<EOF 
a 
b 
c 
EOF 
+1

Chỉ là một FYI. Bạn cũng có thể thực hiện "cat/dev/stdin" trong hàm thay vì lặp lại với "while" – joeb

+1

@joeb: Chỉ đơn giản là 'cat' wi l l work. –

+0

doh. Tất nhiên rồi. Nắm bắt tốt! – joeb

13

Cách đó sẽ có thể là:

printArgs 17 "$(cat <<EOF 
18 
19 
EOF 
)" 

Nhưng tại sao bạn sẽ muốn sử dụng một heredoc cho việc này? heredoc được coi là một tập tin trong lập luận vì vậy bạn phải (ab) sử dụng cat để có được nội dung của file, tại sao không chỉ làm điều gì đó như:

print Args 17 "18 
19" 

Hãy ghi nhớ rằng nó là tốt hơn để thực hiện một kịch bản trên máy bạn muốn ssh và chạy nó sau đó thử một số hack như thế này bởi vì bash sẽ vẫn mở rộng các biến và như vậy trong đối số nhiều dòng của bạn.

+1

Có lẽ phải có một dòng mới giữa 'EOF' và' ("'? –

+0

Tôi muốn vượt qua một biểu mẫu xấu cho Emacs để đánh giá ở chế độ hàng loạt; đây là trường hợp sử dụng hoàn hảo cho "hack" này. –

+0

vài tháng sau, tôi cần phải vượt qua một hình thức xấu xí cho GIMP để đánh giá trong bộ xử lý hàng loạt TinyScheme của nó.Dường như chỉ tiếp tục tăng lên <3 –

1

Một cách để nuôi lệnh ssh qua đây doc và một chức năng là như vậy:

#!/bin/sh 
# define the function 
printArgs() { 
echo "$1" 
ssh -T remotehost 
} 
# call it with a here document supplying its standard input 
printArgs 17 <<EOF 
uname 
uptime 
EOF 

Kết quả:

17 
Linux remotehost 2.6.32-5-686 ... 
Last login: ... 
No mail. 
Linux 
16:46:50 up 4 days, 17:31, 0 users, load average: 0.06, 0.04, 0.01 
0

xargs s hould làm chính xác những gì bạn muốn. Nó chuyển đổi đầu vào tiêu chuẩn để lập luận cho một lệnh (thông báo -0 cho phép để bảo tồn dòng mới)

$ xargs -0 <<EOF printArgs 17 
18 
19 
EOF 

Nhưng đối với bạn trường hợp đặc biệt, tôi đề nghị bạn gửi lệnh trên đầu vào tiêu chuẩn của ssh:

$ ssh host <<EOF 
ls 
EOF 
+1

'xargs' không thể gọi hàm shell vì nó sử dụng' execve() '. Do đó, ràng buộc "bash function" trong câu hỏi là thích hợp - việc kiểm tra với các lệnh thông thường sẽ không làm. –

+0

@CharlesDuffy Tốt bắt – Jezz

3

Building trên câu trả lời của Ned, giải pháp của tôi cho phép hàm nhận đầu vào của nó như là một danh sách đối số hoặc như một heredoc.

printArgs() (
    [[ $# -gt 0 ]] && exec <<< $* 
    ssh -T remotehost 
) 

Vì vậy, bạn có thể làm điều này

printArgs uname 

hay này

printArgs << EOF 
uname 
uptime 
EOF 

Vì vậy, bạn có thể sử dụng các hình thức đầu tiên cho các lệnh đơn và các dạng dài cho nhiều lệnh.

+0

Dễ thương. Rất, rất dễ thương. –