Cách sử dụng thực tế của tùy chọn `set -k` trong bash


16

Khi nào chúng ta sử dụng set -ktùy chọn trong bash?

Hướng dẫn tham khảo Bash nói,

Tất cả các đối số ở dạng câu lệnh gán được đặt trong môi trường cho một lệnh, không chỉ các đối số đứng trước tên lệnh.

Tôi hiểu những gì tùy chọn làm, nhưng không thể tưởng tượng khi chúng ta cần nó.


Nhận thức đúng. Điều này -kcho phép chúng tôi chạy các kịch bản shell 30 năm tuổi mà không cần phải cấu trúc lại chúng. Thay vào đó, vượt qua các biến môi trường tạm thời bằng cách sử dụng cú pháp tiền tố:var1=x var2=y command ...
Henk Langeveld

Câu trả lời:


14

Về cơ bản, bạn có thể sử dụng nó bất cứ lúc nào bạn muốn "tiêm" các biến môi trường được truyền vào tập lệnh shell (dưới dạng đối số) như thể chúng được đặt trong môi trường thông qua export, nhưng không cần phải lưu chúng vĩnh viễn trong exportdanh sách trước khi chạy lệnh .

LƯU Ý: Ngoài ra còn có dạng dài của công -ktắc , set -o keyword.

Thí dụ

$ cat cmd1.bash 
#!/bin/bash

echo $VARCMD

Bây giờ nếu tôi set -k:

$ set -k; ./cmd1.bash VARCMD="hi"; set +k
hi

Nhưng nếu tôi chỉ chạy đoạn script trên:

$ ./cmd1.bash 

$

Xuất khẩu đang làm gì?

$ help export
...
Marks each NAME for automatic export to the environment of subsequently
executed commands.  If VALUE is supplied, assign VALUE before exporting.
...

Vì vậy, nếu chúng ta thêm export | grep VARvào kịch bản của mình như vậy:

$ cat cmd2.bash 
#!/bin/bash

echo $VARCMD
export | grep VAR

Và chúng tôi đã chạy thử nghiệm trên của chúng tôi một lần nữa:

$ set -k; ./cmd2.bash VARCMD="hi"; set +k
hi
declare -x VARCMD="hi"

Nhưng không có set -k:

$ ./cmd2.bash 

$

Vì vậy, set -kcho phép chúng tôi tạm thời xuất các biến số hàng loạt.

Một vi dụ khac

$ cat cmd3.bash 
#!/bin/bash

echo $VARCMD1
echo $VARCMD2
export | grep VAR

Khi chúng tôi đặt nhiều biến, tất cả chúng đều được xuất:

$ set -k; ./cmd3.bash VARCMD1="hi" VARCMD2="bye"; set +k
hi
bye
declare -x VARCMD1="hi"
declare -x VARCMD2="bye"

Vì vậy, sau đó nó chỉ tiêm tất cả các biến môi trường?

Không -klà làm một điều rất rõ ràng ở đây. Nó chỉ xuất các biến được đưa vào dòng lệnh khi lệnh được thực thi.

Thí dụ

Nói rằng tôi đặt biến này:

$ VARCMD1="hi"

Bây giờ khi chúng ta chạy cùng một lệnh bỏ qua VARCMD1="hi":

$  set -k; ./cmd3.bash VARCMD2="bye"; set +k

bye
declare -x VARCMD2="bye"

Nhưng tại sao điều này tồn tại?

Tôi tìm thấy nguồn này giải thích một chút về tính năng này, có tiêu đề: "Chuỗi phân công tham số từ khóa". LƯU Ý: URL nguồn sử dụng địa chỉ IP để tôi không thể liên kết trực tiếp với nó ở đây trên SE.

http://140.120.7.21/OpenSystem2/SoftwareTools/node16.html

Khi lập trình bằng bất kỳ ngôn ngữ nào, biến và giá trị của nó là rất quan trọng để viết mã đáng tin cậy. Bên cạnh các kiểu biến số nguyên và mảng, tất cả các biến shell khác chấp nhận các chuỗi làm giá trị của chúng. Khi nói về ngôn ngữ lập trình shell, để thống nhất, chúng tôi thích cụm từ "tham số từ khóa". Dưới đây là một vài điểm cần chú ý khi gán giá trị cho các tham số từ khóa:

  • Để tránh bất kỳ hiệu ứng không mong muốn nào, luôn đặt chuỗi con gán tham số trước chuỗi lệnh.

    Trong shell B, các giá trị được gán của các tham số từ khóa sẽ được lưu trữ trong các biến shell (cục bộ). Trong bash và ksh, chuỗi gán tham số từ khóa trước lệnh sẽ không được lưu trong các biến shell. Chúng chỉ ảnh hưởng đến quá trình con ngay lập tức rẽ nhánh để thực thi lệnh hiện tại. Chỉ một dòng các chuỗi gán tham số từ khóa được lưu trữ trong các biến shell (cục bộ). Các chuỗi gán tham số từ khóa cũng có thể xuất hiện dưới dạng đối số cho các bí danh, khai báo, sắp chữ, xuất, chỉ đọc và các lệnh dựng sẵn cục bộ. [Phần 3,4 của Tài liệu tham khảo Bash]

  • Các chuỗi gán tham số từ khóa sẽ được coi là đối số cho lệnh được thực thi, nếu chúng được đặt sau tên lệnh.

  • Các tham số từ khóa có thể được thao tác bằng lệnh set.

Trong liên kết này, ss64.com/bash/set.html , vì set -khọ đã đưa ra -o keywordbên cạnh -ktùy chọn. Điều đó có nghĩa gì?
Ramesh

@Ramesh - set -o keywordlà dạng dài của set -k. Xem help set | grep -- '-k'.
slm

à ok Tôi đã gãi đầu trong một thời gian dài để cố gắng hiểu tại sao có 2 lựa chọn. Như câu trả lời hoàn hảo như thường lệ :)
Ramesh

4
./cmd.bash VARCMD=hicần set -kphải làm cho nó hoạt động chính xác theo cách VARCMD=hi ./cmd.bashmà không có set -k. Đoán câu hỏi cụ thể của OP là xung quanh nhu cầu bash để hỗ trợ ./cmd.bash VARCMD=hibiểu mẫu
iruvar

@ 1_CR - điểm tốt. Tôi tin rằng nó phải liên quan đến phong cách hơn bất cứ thứ gì, tôi sẽ xem liệu tôi có thể tìm thấy một nguồn thực tế hay không.
slm

8

Bất kỳ việc sử dụng thực tế set -kcó khả năng chỉ là phong cách cá nhân. Một số - có lẽ những người thích ngôn ngữ lập trình cung cấp khả năng sử dụng đối số từ khóa trong các lệnh gọi hàm hoặc một vài người thích ddcú pháp của lệnh - có thể thích

đặt -k
...
lệnh var 1 = val 1 var 2 = val 2

đến

var 1 = val 1 var 2 = lệnh
 val 2

Lý do thực tế tùy chọn tồn tại trong một số shell được giải thích trong lý do căn bản cho lệnh set trong tiêu chuẩn POSIX :

The following set flags were omitted intentionally with the following rationale:

The -k flag was originally added by the author of the Bourne shell to make it easier
for users of pre-release versions of the shell. In early versions of the Bourne shell
the construct
    set name=value
had to be used to assign values to shell variables.
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.