Làm thế nào để gửi biến đến một shell-script nội tuyến?


26

Tôi chạy đoạn script sau:

VAR="Test"
sh -c 'echo "Hello $VAR"'

Nhưng tôi nhận được:

# ./test.sh
Hello

Làm cách nào tôi có thể gửi biến VARtập lệnh của mình tới trình bao được tạo bằng sh -c '...'?

Câu trả lời:


44

Hoặc sử dụng exportđể biến nó thành một biến môi trường hoặc truyền trực tiếp vào lệnh.

VAR="Test" sh -c 'echo "Hello $VAR"'

VAR="Test"
export VAR
sh -c 'echo "Hello $VAR"'

Tránh sử dụng dấu ngoặc kép xung quanh mã shell để cho phép nội suy vì điều đó đưa ra các lỗ hổng tiêm lệnh như trong:

sh -c "echo 'Xin chào $ VAR'"

gây ra khởi động lại nếu được gọi khi $VARchứa một cái gì đó như';reboot #


Không thực sự thiết thực (tôi có một vài biến và tôi không muốn chúng là biến môi trường), nhưng nó hoạt động, cảm ơn!
Matthieu Napoli

3
@Matthieu: Chúng chỉ được đặt làm biến môi trường cho con của quy trình của bạn , nếu đó là điều khiến bạn lo lắng.
Piskvor

5
Chỉ cần FYI, bạn cũng có thể làm export var="Test"trong một dòng.
dùng606723

@Piskvor cũng cảm ơn bạn vì sự chính xác, điều đó thật hoàn hảo.
Matthieu Napoli

9

Đây là một cách khác để truyền biến cho sh -c(dưới dạng đối số vị trí):

{
VAR="world"
VAR2='!'
sh -c 'echo "Hello ${0}${1}"' "$VAR" "$VAR2"
}

1
(+1) Để giữ cho nó phù hợp hơn với kỳ vọng $ 1 $ 2 thông thường cho các biến tập lệnh, nó có thể có giá trị giả cho $ 0. Điều này sẽ cho phép $@làm việc như mong đợi, ví dụ. sh -c 'echo "Hello $@"' _ "$VAR" "$VAR2"`
Peter.O

2
@ Peter.O Thay vì sử dụng "_", tôi sẽ sử dụng "sh" hoặc một tên hợp lý để đặt cho lệnh đó, vì nó $0được hiển thị trong thông báo lỗi / cảnh báo bằng shell.
Stéphane Chazelas

5

Nếu bạn không muốn xuất chúng dưới dạng các biến môi trường, đây là một mẹo bạn có thể làm. Lưu định nghĩa dao động của bạn vào một tệp .var_init.shvà nguồn nó trong vỏ phụ của bạn như thế này:

.var_init.sh

VAR="Test"

từ dòng lệnh:

sh -c ". .var_init.sh && echo \$VAR" # Make sure to properly escape the '$'

Bằng cách này, bạn chỉ đặt các biến của mình khi thực hiện lớp con.


... hoặcENV=.var_ini.sh sh -c '...'
Kusalananda

Lưu ý rằng nếu .var_init.shdự kiến ​​sẽ được tìm kiếm trong thư mục hiện tại (trái ngược với $PATH), thì nó nên được viết. ./var_init.sh
Stéphane Chazelas
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.