การใช้งานจริงของตัวเลือก `set -k` ใน bash


16

เมื่อไหร่ที่เราจะใช้set -kตัวเลือกในการทุบตี?

คู่มืออ้างอิง Bashกล่าวว่า

อาร์กิวเมนต์ทั้งหมดในรูปแบบของคำสั่งการมอบหมายจะถูกวางไว้ในสภาพแวดล้อมสำหรับคำสั่งไม่ใช่เฉพาะที่นำหน้าชื่อคำสั่ง

ฉันเข้าใจว่าตัวเลือกทำอะไร แต่ไม่สามารถจินตนาการได้เมื่อเราต้องการ


การรับรู้ที่ถูกต้อง การ-kอนุญาตให้เราเรียกใช้เชลล์สคริปต์อายุ 30 ปีโดยไม่จำเป็นต้องปรับโครงสร้างใหม่ ส่งผ่านตัวแปรสภาพแวดล้อมชั่วคราวโดยใช้ไวยากรณ์คำนำหน้าแทน:var1=x var2=y command ...
Henk Langeveld

คำตอบ:


14

โดยทั่วไปคุณสามารถใช้งานได้ทุกเมื่อที่คุณต้องการ "ฉีด" ตัวแปรสภาพแวดล้อมที่ส่งผ่านไปยังเชลล์สคริปต์ (เป็นอาร์กิวเมนต์) ราวกับว่าพวกเขาถูกตั้งค่าภายในสภาพแวดล้อมผ่านexportแต่ไม่จำเป็นต้องให้พวกเขาอยู่ในexportรายการอย่างถาวรก่อนที่จะเรียกใช้คำสั่ง .

หมายเหตุ:นอกจากนี้ยังมีแบบยาวของสวิทช์-kset -o keyword

ตัวอย่าง

$ cat cmd1.bash 
#!/bin/bash

echo $VARCMD

ตอนนี้ถ้าฉันset -k:

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

แต่ถ้าฉันเพียงแค่เรียกใช้สคริปต์ข้างต้น:

$ ./cmd1.bash 

$

การส่งออกกำลังทำอะไร

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

ดังนั้นถ้าเราจะเพิ่มexport | grep VARสคริปต์ของเราเช่น:

$ cat cmd2.bash 
#!/bin/bash

echo $VARCMD
export | grep VAR

และเราก็ทำการทดสอบข้างต้นอีกครั้ง:

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

แต่ไม่มีset -k:

$ ./cmd2.bash 

$

ดังนั้นset -kช่วยให้เราสามารถส่งออกตัวแปรในมวลชั่วคราว

ตัวอย่างอื่น

$ cat cmd3.bash 
#!/bin/bash

echo $VARCMD1
echo $VARCMD2
export | grep VAR

เมื่อเราตั้งค่าตัวแปรหลายตัวตัวแปรทั้งหมดจะถูกส่งออก:

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

ดังนั้นมันจึงเป็นแค่การฉีดตัวแปรสภาพแวดล้อมทั้งหมดหรือไม่

ไม่-kทำสิ่งที่ชัดเจนมากที่นี่ มันเป็นเพียงการส่งออกตัวแปรที่รวมอยู่ในบรรทัดคำสั่งเมื่อคำสั่งถูกดำเนินการ

ตัวอย่าง

พูดว่าฉันตั้งตัวแปรนี้:

$ VARCMD1="hi"

ตอนนี้เมื่อเราเรียกใช้คำสั่งเดียวกันถนัดVARCMD1="hi":

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

bye
declare -x VARCMD2="bye"

แต่ทำไมถึงเกิดขึ้น?

ฉันพบแหล่งข้อมูลนี้ซึ่งอธิบายเกี่ยวกับคุณลักษณะนี้เล็กน้อยชื่อ: "สตริงพารามิเตอร์การกำหนดคำหลัก" หมายเหตุ: URL ต้นทางใช้ที่อยู่ IP ดังนั้นฉันจึงไม่สามารถเชื่อมโยงไปยังที่นี่โดยตรงใน SE

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

เมื่อการเขียนโปรแกรมในภาษาใด ๆ ตัวแปรและค่าของการส่งผ่านเป็นสิ่งสำคัญสำหรับการเขียนรหัสที่เชื่อถือได้ ข้างชนิดตัวแปรจำนวนเต็มและอาร์เรย์ตัวแปรเชลล์อื่นทั้งหมดยอมรับสตริงเป็นค่า เมื่อพูดถึงภาษาการเขียนโปรแกรมเชลล์เพื่อให้สอดคล้องกันเราต้องการวลี "พารามิเตอร์คำหลัก" ต่อไปนี้เป็นข้อควรระวังเมื่อกำหนดค่าให้กับพารามิเตอร์คำหลัก:

  • เพื่อหลีกเลี่ยงผลกระทบที่ไม่คาดคิดให้วางสตริงย่อยการกำหนดพารามิเตอร์ไว้ด้านหน้าของสตริงคำสั่งเสมอ

    ในเชลล์ B ค่าที่กำหนดของพารามิเตอร์คำหลักจะถูกเก็บไว้ในตัวแปรเชลล์ (โลคัล) ใน bash และ ksh สตริงการกำหนดพารามิเตอร์คีย์เวิร์ดคำสั่งก่อนหน้าจะไม่ถูกเก็บไว้ในตัวแปรเชลล์ สิ่งเหล่านี้มีผลกับการประมวลผลย่อยทางแยกทันทีเพื่อดำเนินการคำสั่งปัจจุบัน บรรทัดของสตริงคำหลักที่ได้รับมอบหมายเพียงอย่างเดียวจะได้รับการจัดเก็บไว้ในตัวแปรเชลล์ (โลคัล) สตริงการกำหนดพารามิเตอร์คำสำคัญอาจปรากฏขึ้นเป็นอาร์กิวเมนต์ไปยังคำสั่ง alias, ประกาศ, ประเภท, ส่งออก, อ่านได้อย่างเดียวและคำสั่ง builtin ท้องถิ่น [ส่วน 3.4 ของคู่มืออ้างอิง Bash]

  • สตริงการกำหนดพารามิเตอร์คีย์เวิร์ดจะถูกใช้เป็นอาร์กิวเมนต์สำหรับคำสั่งที่จะดำเนินการหากวางไว้หลังชื่อคำสั่ง

  • พารามิเตอร์คีย์เวิร์ดอาจถูกจัดการโดยคำสั่ง set

ในลิงค์นี้ss64.com/bash/set.htmlเนื่องจากset -kมีให้-o keywordนอกเหนือจาก-kตัวเลือก นั่นแปลว่าอะไร?
Ramesh

@Ramesh - เป็นรูปแบบที่ยาวนานของset -o keyword ดูset -k help set | grep -- '-k'
slm

อาโอเค. ฉันเกาหัวของฉันเป็นเวลานานพยายามที่จะเข้าใจว่าทำไมมี 2 ตัวเลือก เป็นคำตอบที่สมบูรณ์แบบปกติ :)
ราเมษ

4
./cmd.bash VARCMD=hiความต้องการที่set -kจะได้รับมันในการทำงานตรงทางที่ไม่ได้โดยไม่ต้องVARCMD=hi ./cmd.bash set -kเดาคำถามเฉพาะของ OP เกี่ยวกับความจำเป็นในการทุบตีเพื่อสนับสนุน./cmd.bash VARCMD=hiรูปแบบ
iruvar

@ 1_CR - จุดดี ฉันเชื่อว่ามันเกี่ยวข้องกับสไตล์มากกว่าสิ่งใดฉันจะดูว่าฉันสามารถหาแหล่งที่แท้จริงได้หรือไม่
slm

8

การใช้งานจริงของ set -kนั้นเป็นเพียงรูปแบบส่วนตัว บางคน - บางทีผู้ที่ชอบภาษาโปรแกรมที่เสนอความสามารถในการใช้อาร์กิวเมนต์คำหลักในการเรียกใช้ฟังก์ชันหรือบางคนที่ชอบddไวยากรณ์ของคำสั่ง - อาจต้องการ

ชุด -k
...
คำสั่ง var 1 = val 1 var 2 = val 2

ถึง

var 1 = val 1คำสั่ง
 var 2 = val 2

เหตุผลที่แท้จริงของตัวเลือกที่มีอยู่ในบางเชลล์อธิบายไว้ในเหตุผลสำหรับคำสั่ง set ในมาตรฐาน 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.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.