ฉันต้องการให้สคริปต์ของฉันสามารถเลือกอินพุตได้
เช่นปัจจุบันสคริปต์ของฉันคือ
#!/bin/bash
somecommand foo
แต่ฉันอยากจะบอกว่า:
#!/bin/bash
somecommand [ if $1 exists, $1, else, foo ]
ฉันต้องการให้สคริปต์ของฉันสามารถเลือกอินพุตได้
เช่นปัจจุบันสคริปต์ของฉันคือ
#!/bin/bash
somecommand foo
แต่ฉันอยากจะบอกว่า:
#!/bin/bash
somecommand [ if $1 exists, $1, else, foo ]
คำตอบ:
คุณสามารถใช้ไวยากรณ์ค่าเริ่มต้น:
somecommand ${1:-foo}
ข้างต้นจะอธิบายไว้ในทุบตี Reference Manual - 3.5.3 ขยายเชลล์พารามิเตอร์ [ผมขอย้ำ]:
หากพารามิเตอร์ไม่ได้ตั้งค่าหรือเป็นโมฆะการขยายตัวของคำจะถูกแทนที่ มิฉะนั้นค่าของพารามิเตอร์จะถูกแทนที่
หากคุณต้องการแทนที่ค่าเริ่มต้นหากพารามิเตอร์ไม่ได้ถูกตั้งค่าไว้ (แต่ไม่ใช่ถ้าเป็นค่าว่างเช่นถ้าไม่ใช่สตริงว่าง) ให้ใช้ไวยากรณ์นี้แทน:
somecommand ${1-foo}
อีกครั้งจากคู่มืออ้างอิง Bash - การขยายพารามิเตอร์เชลล์ 3.5.3 :
การละเว้นโคลอนจะทำให้เกิดการทดสอบสำหรับพารามิเตอร์ที่ไม่ได้ตั้งค่าไว้เท่านั้น ใส่อีกวิธีหนึ่งถ้ามีเครื่องหมายโคลอนอยู่ด้วยโอเปอเรเตอร์จะทดสอบการมีอยู่ของพารามิเตอร์ทั้งสองและค่าไม่เป็นโมฆะ หากไม่ใส่เครื่องหมายจุดคู่ผู้ปฏิบัติงานจะทดสอบเฉพาะเมื่อมี
foo
ถ้า$1
ไม่ได้ตั้งค่าหรือสตริงว่าง " และ${1-foo}
"กลับมาfoo
ถ้า$1
ไม่ได้ตั้งค่า"
คุณสามารถตั้งค่าเริ่มต้นสำหรับตัวแปรดังนี้:
#!/usr/bin/env bash
ARG1=${1:-foo}
ARG2=${2:-bar}
ARG3=${3:-1}
ARG4=${4:-$(date)}
echo "$ARG1"
echo "$ARG2"
echo "$ARG3"
echo "$ARG4"
นี่คือตัวอย่างของวิธีการทำงาน:
$ ./somecommand.sh
foo
bar
1
Thu Mar 29 10:03:20 ADT 2018
$ ./somecommand.sh ez
ez
bar
1
Thu Mar 29 10:03:40 ADT 2018
$ ./somecommand.sh able was i
able
was
i
Thu Mar 29 10:03:54 ADT 2018
$ ./somecommand.sh "able was i"
able was i
bar
1
Thu Mar 29 10:04:01 ADT 2018
$ ./somecommand.sh "able was i" super
able was i
super
1
Thu Mar 29 10:04:10 ADT 2018
$ ./somecommand.sh "" "super duper"
foo
super duper
1
Thu Mar 29 10:05:04 ADT 2018
$ ./somecommand.sh "" "super duper" hi you
foo
super duper
hi
you
-
สับสนฉัน (มันเมื่อตะกี้?)
if [ ! -z $1 ]
then
: # $1 was given
else
: # $1 was not given
fi
-n
! -z
เป็นเช่นเดียวกับ
-n
และ! -z
ดังนั้นฉันจะบอกว่าไม่ได้เป็นกรณีที่นี่
[ -n $1 ]
จะเป็นจริงเสมอ หากคุณใช้ทุบตี[[ -n $1 ]]
จะทำงานตามที่คุณคาดหวังมิฉะนั้นคุณต้องพูด[ -n "$1" ]
คุณสามารถตรวจสอบจำนวนอาร์กิวเมนต์ด้วย $#
#!/bin/bash
if [ $# -ge 1 ]
then
$1
else
foo
fi
โปรดอย่าลืมถ้าตัวแปร $ 1 .. $ n คุณต้องเขียนถึงตัวแปรปกติเพื่อใช้การทดแทน
#!/bin/bash
NOW=$1
echo ${NOW:-$(date +"%Y-%m-%d")}
DAY=${1:-$(date +%F -d "yesterday")}
สำหรับอาร์กิวเมนต์หลายตัวเลือกโดยเปรียบเทียบกับls
คำสั่งที่สามารถใช้หนึ่งไฟล์ขึ้นไปหรือตามค่าเริ่มต้นจะแสดงรายการทุกอย่างในไดเรกทอรีปัจจุบัน:
if [ $# -ge 1 ]
then
files="$@"
else
files=*
fi
for f in $files
do
echo "found $f"
done
ไม่ทำงานอย่างถูกต้องสำหรับไฟล์ที่มีช่องว่างในเส้นทางอนิจจา ยังไม่ได้คิดวิธีการทำงานที่ยัง
สิ่งนี้อนุญาตให้มีค่าเริ่มต้นสำหรับ ARG ตัวเลือกที่ 1 และเก็บรักษาไว้หลาย args
> cat mosh.sh
set -- ${1:-xyz} ${@:2:$#} ; echo $*
> mosh.sh
xyz
> mosh.sh 1 2 3
1 2 3
เป็นไปได้ที่จะใช้การทดแทนตัวแปรเพื่อทดแทนค่าคงที่หรือคำสั่ง (เช่นdate
) สำหรับอาร์กิวเมนต์ คำตอบที่ได้มุ่งเน้นไปที่ค่าคงที่ แต่นี่คือสิ่งที่ฉันใช้เพื่อทำให้วันที่อาร์กิวเมนต์ตัวเลือก:
~$ sh co.sh
2017-01-05
~$ sh co.sh 2017-01-04
2017-01-04
~$ cat co.sh
DAY=${1:-$(date +%F -d "yesterday")}
echo $DAY