ความหมายของ [“ $ {1: 0: 1}” = '-']


18

ฉันมีสคริปต์ต่อไปนี้เพื่อเริ่มกระบวนการ MySQL:

if [ "${1:0:1}" = '-' ]; then
    set -- mysqld_safe "$@"
fi

if [ "$1" = 'mysqld_safe' ]; then
    DATADIR="/var/lib/mysql"
...

1: 0: 1 หมายถึงอะไรในบริบทนี้


1
ฉันอยากจะรู้คำตอบจริงๆ แต่ฉันรู้สึกว่านี่เป็นคำถามที่แคบเกินไปสำหรับเอสเอฟ ฉันลงคะแนนเพื่อย้ายข้อมูลไปยังไซต์ Unix
Massimo

คำตอบ:


19

มันคือการทดสอบสำหรับ-ตัวเลือกการประที่เห็นได้ชัด มันแปลกนิดหน่อยจริงๆ มันใช้ไม่ได้มาตรฐานการขยายตัวในความพยายามที่จะดึงคนแรกและคนเดียวที่ตัวอักษรตัวแรกจากbash $1นี่0คือดัชนีอักขระส่วนหัวและ1ความยาวของสตริงคือ ใน[ testลักษณะที่อาจเป็น:

[ " -${1#?}" = " $1" ]

การเปรียบเทียบไม่เหมาะอย่างยิ่งtestเพราะมันตีความการ-ขัดแย้งประเช่นกัน - ซึ่งเป็นเหตุผลที่ฉันใช้พื้นที่ชั้นนำที่นั่น

วิธีที่ดีที่สุดในการทำสิ่งนี้ - และวิธีที่มักจะทำ - คือ:

case $1 in -*) mysqld_safe "$@"; esac

1
ปิด; ตัวเลขที่ตามหลังเครื่องหมายโคลอนที่สอง${1:0:1}คือความยาวไม่ใช่ดัชนี
chepner

ด้วยวิธีการทุบตีด้วย[[: [[ $1 == -* ]].
Arthur2e5

2
โดยส่วนตัวฉันไม่คิดว่าสิ่งเหล่า-นี้จะเป็นปัญหาสำหรับtestที่นี่POSIXให้คำจำกัดความของความหมายโดยการนับอาร์กิวเมนต์ เนื่องจากไม่มีตัวเลือกดังกล่าวที่ใช้สองข้อโต้แย้งมันควรจะปลอดภัยที่จะเขียนในดิบ
Arthur2e5

@ Arthur2e5 - ถูกต้อง - ไม่น่ามีปัญหา - และมีโอกาสมากที่จะไม่เป็นปัญหาเลย มันยังคงเป็นวิธีที่แปลกที่จะไป - เพียงแค่ไม่พอดี สิ่งที่ไม่[[ : [[ทำอะไร?
mikeserv

1
@mikeserv คุณควรดูที่หน้าเว็บ (ถ้าคุณอ่านจากที่อื่น) .. ความคิดเห็นของฉันเหมือน 'กับ START_CODE [[END_CODE: START_CODE [[$ 1 == - *]] END_CODE' อันแรก[[เป็นเพียงชื่อไวยากรณ์และเครื่องหมายโคลอนเป็นเครื่องหมายวรรคตอน
Arthur2e5

11

นี่จะใช้สตริงย่อยของ$1ตั้งแต่ 0 ถึงตัวที่ 1 ดังนั้นคุณจะได้ตัวอักษรตัวแรกและตัวอักษรตัวแรกของสตริง

จากbashหน้า man 3.2:

  ${parameter:offset}
  ${parameter:offset:length}
          Substring  Expansion.   Expands  to  up to length characters of
          parameter starting at the character specified  by  offset.   If
          length is omitted, expands to the substring of parameter start-
          ing at the character specified by offset.   length  and  offset
          are  arithmetic  expressions (see ARITHMETIC EVALUATION below).
          length must evaluate to a number greater than or equal to zero.
          If  offset  evaluates  to a number less than zero, the value is
          used as an offset from the end of the value of  parameter.   If
          parameter  is  @,  the  result  is length positional parameters
          beginning at offset.  If parameter is an array name indexed  by
          @ or *, the result is the length members of the array beginning
          with ${parameter[offset]}.  A negative offset is taken relative
          to  one  greater than the maximum index of the specified array.
          Note that a negative offset must be separated from the colon by
          at  least  one space to avoid being confused with the :- expan-
          sion.  Substring indexing is zero-based unless  the  positional
          parameters are used, in which case the indexing starts at 1.

6

มันคือการทดสอบว่าตัวอักษรตัวแรกของอาร์กิวเมนต์แรกเป็นเส้นประ$1-

1: 0: 1 ${parameter:offset:length}เป็นค่าสำหรับการขยายตัวพารามิเตอร์:

นั่นหมายความว่า:

  • ชื่อ: พารามิเตอร์ชื่อ1เช่น:$1
  • เริ่ม: จากตัวอักษรตัวแรก0(หมายเลขจาก 0)
  • ความยาว: 1 ตัว

ในระยะสั้น: $1ตัวอักษรตัวแรกของพารามิเตอร์ตำแหน่งแรก
การขยายพารามิเตอร์นั้นมีอยู่ใน ksh, bash, zsh (อย่างน้อย)


หากคุณต้องการเปลี่ยนบรรทัดทดสอบ:

[ "${1:0:1}" = "-" ]

ตัวเลือกทุบตี

วิธีทุบตีปลอดภัยอื่น ๆ อาจเป็น:

[[ $1 =~ ^- ]]
[[ $1 == -* ]]

ปลอดภัยกว่าเนื่องจากไม่มีปัญหาในการอ้างอิง (ไม่มีการแยกภายใน[[)

ตัวเลือก POSIXly

สำหรับกระสุนเก่าที่มีความสามารถน้อยกว่าสามารถเปลี่ยนเป็น:

[ "$(echo $1 | cut -c 1)" = "-" ]
[ "${1%%"${1#?}"}"        = "-" ]
case $1 in  -*) set -- mysqld_safe "$@";; esac

เฉพาะคำสั่ง case ที่ทนต่อการอ้างอิงที่ผิดมากขึ้น

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