คำถามติดแท็ก variable

ตัวแปรคือชื่อถ้าเลือกอย่างถูกต้องด้วยความหมายเชิงสัญลักษณ์ที่เก็บค่าหรือค่า ใช้แท็กนี้หากคำถามของคุณเกี่ยวกับการใช้ตัวแปรในการเขียนสคริปต์เชลล์ (หากคุณต้องการถามเกี่ยวกับตัวแปรในภาษาการเขียนโปรแกรมคุณควรถามเกี่ยวกับ StackOverflow)

2
วิธีการแทรกตัวแปรภายในสตริงที่มี“”?
ฉันต้องการสร้างสตริง xml โดยการแทรกตัวแปร: str1="Hello" str2="world" xml='<?xml version="1.0" encoding="iso-8859-1"?><tag1>$str1</tag1><tag2>$str2</tag2>' echo $xml ผลลัพธ์ที่ควรจะเป็น <?xml version="1.0" encoding="iso-8859-1"?><tag1>Hello</tag1><tag2>world</tag2> แต่สิ่งที่ฉันได้คือ: <?xml version="1.0" encoding="iso-8859-1"?><tag1>$str1</tag1><tag2>$str2</tag2> ฉันก็ลอง xml="<?xml version="1.0" encoding="iso-8859-1"?><tag1>$str1</tag1><tag2>$str2</tag2>" แต่จะลบเครื่องหมายคำพูดคู่ด้านในและให้ <?xml version=1.0 encoding=iso-8859-1?><tag1>hello</tag1><tag2>world</tag2>
25 bash  shell  variable  xml 

4
เหตุใดตัวแปรภายในของฉันจึงอยู่ใน 'ขณะที่อ่าน' แต่ไม่ใช่ในวงอื่นที่คล้ายกัน
เหตุใดฉันจึงได้รับค่าต่าง ๆ$xจากตัวอย่างด้านล่าง #!/bin/bash x=1 echo fred > junk ; while read var ; do x=55 ; done < junk echo x=$x # x=55 .. I'd expect this result x=1 cat junk | while read var ; do x=55 ; done echo x=$x # x=1 .. but why? x=1 echo fred …


5
ทำไมต้องใช้เครื่องหมายคำพูดคู่ในการทดสอบ [[]]
สมมติว่าเรามีจำนวนเต็ม 2 ตัวในสคริปต์ทุบตี: value1=5 value2=3 แล้วทำไมเราต้องใช้เครื่องหมายคำพูดคู่ในกรณีของการทดสอบ? ตัวอย่างเช่น: if [[ "$value1" -eq "$value2" ]] ทำไมไม่ลองใช้สิ่งต่อไปนี้? if [[ $value1 -eq $value2 ]] สำหรับฉันการเสนอราคาสองครั้งไม่สมเหตุสมผลเลย
23 bash  shell  quoting  variable  test 


3
ฉันจะขยายตัวแปรที่ยกมาเป็นอะไรถ้ามันว่างเปล่า?
ว่าฉันมีสคริปต์ทำ: some-command "$var1" "$var2" ... และในกรณีที่var1ว่างเปล่าฉันอยากจะแทนที่ด้วยไม่มีอะไรแทนที่สตริงว่างดังนั้นคำสั่งที่ดำเนินการคือ: some-command "$var2" ... และไม่: some-command '' "$var2" ... มีวิธีที่ง่ายกว่าการทดสอบตัวแปรและเงื่อนไขรวมถึงมันได้หรือไม่ if [ -n "$1" ]; then some-command "$var1" "$var2" ... # or some variant using arrays to build the command # args+=("$var1") else some-command "$var2" ... fi มีการทดแทนพารามิเตอร์มากกว่าที่สามารถขยายไปเป็นอะไรใน bash, zsh หรือไม่ชอบ? ฉันอาจยังต้องการใช้ globbing ในส่วนที่เหลือของข้อโต้แย้งดังนั้นการปิดการใช้งานและการเลิกตัวแปรไม่ได้เป็นตัวเลือก

2
การตั้งค่าตัวแปรเชลล์ในแบบรวมศูนย์เป็นโมฆะ
ฉันชอบ "null coalescing" จริง ๆ ซึ่งคุณสามารถตั้งค่าตัวแปรเป็นค่า "ไม่ใช่ null" ครั้งแรกในรายการของสิ่งต่าง ๆ หลายภาษารองรับสิ่งนี้เช่น: ค#: String myStr = string1 ?? string2 ?? "default"; JavaScript: var myStr = string1 || string2 || "default"; ... ฯลฯ ฉันแค่อยากรู้ว่าสิ่งนี้สามารถทำได้ใน Bash เพื่อตั้งค่าตัวแปรหรือไม่? หลอก: MY_STR=$ENV{VAR_NAME}??$ANOTHER_VAR??"default";
20 bash  shell  variable 

4
dirname และ basename เทียบกับการขยายพารามิเตอร์
มีเหตุผลใดที่จะชอบอีกรูปแบบหนึ่งหรือไม่ ประสิทธิภาพความน่าเชื่อถือความสะดวกในการพกพา? filename=/some/long/path/to/a_file parentdir_v1="${filename%/*}" parentdir_v2="$(dirname "$filename")" basename_v1="${filename##*/}" basename_v2="$(basename "$filename")" echo "$parentdir_v1" echo "$parentdir_v2" echo "$basename_v1" echo "$basename_v2" ผลิต: /some/long/path/to /some/long/path/to a_file a_file (v1 ใช้การขยายพารามิเตอร์เชลล์ v2 ใช้ไบนารีภายนอก)

4
ยกเว้นตัวแปรสำหรับใช้เป็นเนื้อหาของสคริปต์อื่น
คำถามนี้ไม่เกี่ยวกับวิธีเขียนสตริงตัวอักษรที่ใช้ Escape อย่างเหมาะสม ฉันไม่พบคำถามที่เกี่ยวข้องซึ่งไม่เกี่ยวกับวิธีการหลีกเลี่ยงตัวแปรเพื่อการบริโภคโดยตรงภายในสคริปต์หรือโดยโปรแกรมอื่น ๆ เป้าหมายของฉันคือการเปิดใช้งานสคริปต์เพื่อสร้างสคริปต์อื่น ๆ เนื่องจากงานในสคริปต์ที่สร้างขึ้นจะทำงานที่ใดก็ได้ตั้งแต่ 0 ถึงnครั้งในเครื่องอื่นและข้อมูลที่สร้างขึ้นอาจเปลี่ยนแปลงก่อนที่จะทำงาน (อีกครั้ง) ดังนั้นการดำเนินการโดยตรงผ่านเครือข่ายจะ ไม่ทำงาน. รับทราบตัวแปรที่อาจมีตัวอักษรพิเศษเช่นคำพูดเดียวฉันต้องเขียนออกมาเป็นตัวอักษรสตริงหนีเต็มอย่างเช่นตัวแปรfooที่มีbar'bazควรจะปรากฏในสคริปต์ที่สร้างขึ้นเป็น: qux='bar'\''baz' ซึ่งจะเขียนโดยการต่อท้าย"qux=$foo_esc"บรรทัดอื่นของสคริปต์ ฉันใช้ Perl แบบนี้: foo_esc="'`perl -pe 's/('\'')/\\1\\\\\\1\\1/g' <<<"$foo"`'" แต่ดูเหมือนว่าเกินความจริง ฉันไม่ประสบความสำเร็จในการทำมันด้วยการทุบตีคนเดียว ฉันได้ลองหลายแบบแล้ว: foo_esc="'${file//\'/\'\\\'\'}'" foo_esc="'${file//\'/'\\''}'" แต่เครื่องหมายสแลชพิเศษอาจปรากฏในเอาต์พุต (เมื่อฉันทำecho "$foo") หรือพวกเขาทำให้เกิดข้อผิดพลาดทางไวยากรณ์ (ต้องการอินพุตเพิ่มเติมหากทำจากเชลล์)


5
ไปป์กำหนดตัวแปร
เพื่อความเรียบง่ายฉันต้องการทำ: echo cart | assign spo; echo $spo เอาท์พุท: รถเข็น มีassignแอปพลิเคชันดังกล่าวอยู่หรือไม่? ฉันตระหนักถึงวิธีทั้งหมดในการทำเช่นนี้โดยใช้การทดแทน
19 bash  variable 

3
การใช้ตัวแปรเชลล์สำหรับตัวเลือกคำสั่ง
ในสคริปต์ Bash ฉันพยายามจัดเก็บตัวเลือกที่ใช้rsyncในตัวแปรแยกต่างหาก ใช้งานได้ดีกับตัวเลือกง่าย ๆ (เช่น--recursive) แต่ฉันพบปัญหากับ--exclude='.*': $ find source source source/.bar source/foo $ rsync -rnv --exclude='.*' source/ dest sending incremental file list foo sent 57 bytes received 19 bytes 152.00 bytes/sec total size is 0 speedup is 0.00 (DRY RUN) $ RSYNC_OPTIONS="-rnv --exclude='.*'" $ rsync $RSYNC_OPTIONS source/ dest sending …
19 bash  variable 

1
เหตุใด $ {$ #} จึงให้ผลลัพธ์แบบเดียวกันกับ $$ ในเชลล์
ขณะที่พยายามที่จะได้รับที่ผ่านมาชุดพารามิเตอร์ตำแหน่งในฉันได้พยายาม/bin/dash echo ${$#}น่าแปลกที่นี่ไม่ได้ส่งผลให้เกิดข้อผิดพลาด แต่เป็น PID ซึ่งเหมือนกับ$$เนื้อหาตัวแปร คำถามทำไมไวยากรณ์นั้นถึงใช้ได้? กฎไวยากรณ์ที่เชลล์ใช้ในที่นี้คืออะไร โดยทั่วไปสิ่งที่ฉันทำคือ $ set 1 2 3 4 5 $ echo ${$#} 13819 $ echo $$ 13819 เห็นได้ชัดว่า%ตัวละครยังได้รับการละเว้นในโครงสร้างดังกล่าว $ echo ${$%} 13819 แต่*และ@ส่งผลให้เกิดข้อผิดพลาดในการทดแทนที่ไม่ดี: $ echo ${$*} sh: 10: Bad substitution $ echo ${$@} sh: 11: Bad substitution
18 shell  variable 

3
เหตุใดตัวเลือกในตัวแปรที่ยกมาจึงล้มเหลว แต่ทำงานเมื่อไม่ได้อ้างอิง
ฉันอ่านเกี่ยวกับว่าฉันควรอ้างอิงตัวแปรใน bash เช่น "$ foo" แทนที่จะเป็น $ foo อย่างไรก็ตามในขณะที่เขียนสคริปต์ฉันพบกรณีที่ใช้ได้โดยไม่ต้องใส่เครื่องหมายคำพูด แต่ไม่ใช่กับพวกเขา: wget_options='--mirror --no-host-directories' local_root="$1" # ./testdir recieved from command line remote_root="$2" # ftp://XXX recieved from command line relative_path="$3" # /XXX received from command line อันนี้ใช้ได้ผล: wget $wget_options --directory_prefix="$local_root" "$remote_root$relative_path" อันนี้ไม่ (บันทึกคำพูดคู่ aroung $ wget_options): wget "$wget_options" --directory_prefix="$local_root" "$remote_root$relative_path" อะไรคือสาเหตุของสิ่งนี้? บรรทัดแรกเป็นเวอร์ชั่นที่ดี; หรือฉันควรสงสัยว่ามีข้อผิดพลาดที่ซ่อนอยู่ที่ไหนสักแห่งที่ทำให้เกิดพฤติกรรมนี้? …

6
ควรอ้างอิงตัวแปรเมื่อดำเนินการหรือไม่
กฎทั่วไปในการเขียนสคริปต์เปลือกคือตัวแปรที่ควรจะยกมาเว้นแต่จะมีเหตุผลที่น่าสนใจที่จะไม่ สำหรับรายละเอียดมากกว่าที่คุณอาจต้องการทราบลองดูที่ Q&A ที่ยอดเยี่ยมนี้: ผลกระทบด้านความปลอดภัยของการลืมอ้างตัวแปรใน bash / POSIX shellsเปลือกหอย พิจารณาอย่างไรก็ตามฟังก์ชั่นเช่นนี้: run_this(){ $@ } ควร$@จะยกมามีหรือไม่? ฉันเล่นกับมันสักครู่และไม่พบกรณีใด ๆ ที่การขาดคำพูดทำให้เกิดปัญหา ในทางกลับกันการใช้เครื่องหมายคำพูดทำให้หยุดพักเมื่อส่งคำสั่งที่มีช่องว่างเป็นตัวแปรที่ยกมา: #!/usr/bin/sh set -x run_this(){ $@ } run_that(){ "$@" } comm="ls -l" run_this "$comm" run_that "$comm" การเรียกใช้สคริปต์ด้านบนส่งคืน: $ a.sh + comm='ls -l' + run_this 'ls -l' + ls -l total 8 -rw-r--r-- 1 …

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.