Penggunaan praktis opsi `set -k` di bash

16

Kapan kami menggunakan set -kopsi dalam bash?

Manual referensi Bash mengatakan,

Semua argumen dalam bentuk pernyataan penugasan ditempatkan di lingkungan untuk suatu perintah, bukan hanya yang mendahului nama perintah.

Saya mengerti apa pilihannya, tetapi tidak bisa membayangkan kapan kami membutuhkannya.

MS.Kim
sumber
Persepsi yang benar. Hal ini -kmemungkinkan kita untuk menjalankan skrip shell berusia 30 tahun tanpa perlu refactor. Lewati variabel lingkungan sementara menggunakan sintaks awalan sebagai gantinya:var1=x var2=y command ...
Henk Langeveld

Jawaban:

14

Anda pada dasarnya dapat menggunakannya kapan saja Anda ingin "menyuntikkan" variabel lingkungan yang dilewatkan ke dalam skrip shell (sebagai argumen) seolah-olah mereka ditetapkan dalam lingkungan melalui export, tetapi tanpa harus memilikinya secara permanen berada di exportdaftar sebelum menjalankan perintah .

CATATAN: Ada juga bentuk -ksaklar yang panjang set -o keyword,.

Contoh

$ cat cmd1.bash 
#!/bin/bash

echo $VARCMD

Sekarang jika saya set -k:

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

Tetapi jika saya menjalankan skrip di atas:

$ ./cmd1.bash 

$

Apa yang ekspor lakukan?

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

Jadi jika kita ingin menambahkan export | grep VARskrip kita seperti ini:

$ cat cmd2.bash 
#!/bin/bash

echo $VARCMD
export | grep VAR

Dan kami menjalankan tes kami di atas lagi:

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

Tapi tanpa set -k:

$ ./cmd2.bash 

$

Jadi set -kmemungkinkan kita untuk sementara mengekspor variabel secara massal.

Contoh lain

$ cat cmd3.bash 
#!/bin/bash

echo $VARCMD1
echo $VARCMD2
export | grep VAR

Ketika kami menetapkan beberapa variabel, mereka semua diekspor:

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

Jadi itu hanya menyuntikkan semua variabel lingkungan?

Tidak -kadalah melakukan hal yang sangat eksplisit di sini. Itu hanya mengekspor variabel yang dimasukkan pada baris perintah ketika perintah dieksekusi.

Contoh

Katakanlah saya menetapkan variabel ini:

$ VARCMD1="hi"

Sekarang ketika kita menjalankan perintah yang sama menghilangkan VARCMD1="hi":

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

bye
declare -x VARCMD2="bye"

Tetapi mengapa ini ada?

Saya menemukan sumber ini yang menjelaskan sedikit tentang fitur ini, berjudul: "Strings Assignment Parameter Kata Kunci". CATATAN: URL sumber menggunakan alamat IP sehingga saya tidak dapat menautkannya langsung di sini di SE.

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

Saat memprogram dalam bahasa apa pun, variabel dan nilainya yang lewat sangat penting untuk menulis kode yang andal. Di samping tipe variabel integer dan array, semua variabel shell lainnya menerima string sebagai nilainya. Ketika berbicara tentang bahasa pemrograman shell, agar konsisten, kami lebih suka frasa "parameter kata kunci". Berikut adalah beberapa hal yang harus diperhatikan ketika menetapkan nilai ke parameter kata kunci:

  • Untuk menghindari efek yang tidak diharapkan, selalu tempatkan substring penugasan parameter di depan string perintah.

    Dalam shell B, nilai yang ditetapkan dari parameter kata kunci akan disimpan dalam variabel shell (lokal). Dalam bash dan ksh, perintah penugasan parameter kata kunci sebelum perintah tidak akan disimpan dalam variabel shell. Mereka hanya mempengaruhi subproses langsung yang bercabang untuk menjalankan perintah saat ini. Satu baris string penetapan parameter kata kunci saja disimpan dalam variabel shell (lokal). String penetapan parameter kata kunci juga dapat muncul sebagai argumen untuk alias, mendeklarasikan, mengeset, mengekspor, hanya baca, dan perintah builtin lokal. [Bagian 3.4 dari Manual Referensi Bash]

  • String penetapan parameter kata kunci akan diperlakukan sebagai argumen untuk perintah yang akan dieksekusi, jika ditempatkan setelah nama perintah.

  • Parameter kata kunci dapat dimanipulasi oleh perintah set.
slm
sumber
Di tautan ini, ss64.com/bash/set.html , karena set -kmereka telah memberikan opsi -o keywordselain -k. Apakah itu berarti sesuatu?
Ramesh
@ Ramesh - set -o keywordadalah bentuk panjang dari set -k. Lihat help set | grep -- '-k'.
slm
ah baiklah Saya menggaruk-garuk kepala untuk waktu yang lama mencoba memahami mengapa ada 2 opsi. Seperti jawaban sempurna yang biasa :)
Ramesh
4
./cmd.bash VARCMD=hiperlu set -kmembuatnya berfungsi persis seperti yang VARCMD=hi ./cmd.bashdilakukan tanpa set -k. Tebak pertanyaan khusus OP adalah seputar perlunya bash untuk mendukung ./cmd.bash VARCMD=hiformulir
iruvar
@ 1_CR - poin bagus. Saya percaya itu ada hubungannya dengan gaya lebih dari apa pun, saya akan melihat apakah saya dapat menemukan sumber yang sebenarnya.
slm
8

Penggunaan praktis apa set -kpun mungkin hanya gaya pribadi. Beberapa - mungkin mereka yang menyukai bahasa pemrograman yang menawarkan kemampuan untuk menggunakan argumen kata kunci dalam panggilan fungsi, atau beberapa orang yang menyukai ddsintaksis perintah - mungkin lebih suka

set -k
...
perintah var 1 = val 1 var 2 = val 2

untuk

var 1 = val 1 var 2 = perintah
 val 2

Alasan sebenarnya opsi ada di beberapa shell dijelaskan dalam alasan untuk perintah yang ditetapkan dalam standar 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.
Tandai Plotnick
sumber