Bash script - nội dung biến như một lệnh để chạy


159

Tôi có một tập lệnh Perl cung cấp cho tôi một danh sách các số ngẫu nhiên được xác định tương ứng với các dòng của một tệp. Tiếp theo tôi muốn trích xuất những dòng đó từ tập tin bằng cách sử dụng sed.

#!/bin/bash
count=$(cat last_queries.txt | wc -l)
var=$(perl test.pl test2 $count)

Biến vartrả về một đầu ra như : cat last_queries.txt | sed -n '12p;500p;700p'. Vấn đề là tôi không thể chạy lệnh cuối cùng này. Tôi đã thử với $var, nhưng đầu ra không chính xác (nếu tôi chạy thủ công lệnh thì nó hoạt động tốt, vì vậy không có vấn đề gì ở đó). cách chính xác để làm điều này là gì?

Tái bút: Chắc chắn tôi có thể làm tất cả công việc trong Perl, nhưng tôi đang cố gắng học theo cách này, vì nó có thể giúp tôi trong các tình huống khác.

Câu trả lời:


215

Bạn chỉ cần làm:

#!/bin/bash
count=$(cat last_queries.txt | wc -l)
$(perl test.pl test2 $count)

Tuy nhiên, nếu bạn muốn gọi lệnh Perl của mình sau đó và đó là lý do tại sao bạn muốn gán nó cho một biến, thì:

#!/bin/bash
count=$(cat last_queries.txt | wc -l)
var="perl test.pl test2 $count" # You need double quotes to get your $count value substituted.

...stuff...

eval $var

Theo sự giúp đỡ của Bash:

~$ help eval
eval: eval [arg ...]
    Execute arguments as a shell command.

    Combine ARGs into a single string, use the result as input to the shell,
    and execute the resulting commands.

    Exit Status:
    Returns exit status of command or success if command is null.


2
line=$((${RANDOM} % $(wc -l < /etc/passwd)))
sed -n "${line}p" /etc/passwd

chỉ với tập tin của bạn thay vào đó.

Trong ví dụ này tôi đã sử dụng tệp / etc / password, sử dụng biến đặc biệt ${RANDOM}(về điều tôi đã học ở đây) và sedbiểu thức bạn có, chỉ khác là tôi đang sử dụng dấu ngoặc kép thay vì đơn lẻ để cho phép mở rộng biến.


2

Trong trường hợp bạn có nhiều biến chứa các đối số cho lệnh bạn đang chạy và không chỉ là một chuỗi, bạn không nên sử dụng eval trực tiếp, vì nó sẽ thất bại trong trường hợp sau:

function echo_arguments() {
  echo "Argument 1: $1"
  echo "Argument 2: $2"
  echo "Argument 3: $3"
  echo "Argument 4: $4"
}

# Note we are passing 3 arguments to `echo_arguments`, not 4
eval echo_arguments arg1 arg2 "Some arg"

Kết quả:

Argument 1: arg1
Argument 2: arg2
Argument 3: Some
Argument 4: arg

Lưu ý rằng mặc dù "Một số đối số" đã được thông qua dưới dạng một đối số, evalhãy đọc nó thành hai.

Thay vào đó, bạn chỉ có thể sử dụng chuỗi như chính lệnh:

# The regular bash eval works by jamming all its arguments into a string then
# evaluating the string. This function treats its arguments as individual
# arguments to be passed to the command being run.
function eval_command() {
  "$@";
}

Lưu ý sự khác biệt giữa đầu ra evaleval_commandchức năng mới :

eval_command echo_arguments arg1 arg2 "Some arg"

Kết quả:

Argument 1: arg1
Argument 2: arg2
Argument 3: Some arg
Argument 4:

1
Để tránh việc đánh giá từng yếu tố sau không gian, như trong ví dụ đầu tiên của bạn với eval, hãy bọc nó bằng dấu ngoặc đơn : eval 'echo_arguments arg1 arg2 "Some arg"'. Sau đó, đầu ra sẽ như trong ví dụ thứ hai của bạn.
Noam Manos
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.