Ý nghĩa của [Hồi $ {1: 0: 1} Mạnh = '-']


18

Tôi có đoạn script sau để khởi chạy quy trình MySQL:

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

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

1: 0: 1 có nghĩa là gì trong bối cảnh này?


1
Tôi thực sự muốn biết câu trả lời, nhưng tôi cảm thấy đây là một câu hỏi quá hẹp đối với SF. Tôi đang bỏ phiếu để di chuyển nó đến trang web Unix.
Massimo

Câu trả lời:


19

Rõ ràng, đây là một thử nghiệm cho một -tùy chọn đối số nét đứt. Thật là hơi lạ. Nó sử dụng một bản bashmở rộng không chuẩn trong một nỗ lực để trích xuất ký tự đầu tiên và duy nhất từ ​​đó $1. Các 0là chỉ số nhân vật đứng đầu và 1là chiều dài chuỗi. Tương [ testtự như vậy, nó cũng có thể là:

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

Không có sự so sánh nào đặc biệt phù hợp với testmặc dù, vì nó cũng diễn giải các -đối số có dấu gạch ngang - đó là lý do tại sao tôi sử dụng không gian hàng đầu ở đó.

Cách tốt nhất để làm điều này - và cách nó thường được thực hiện - là:

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

1
Gần; số theo dấu hai chấm thứ hai ${1:0:1}là một chiều dài, không phải là một chỉ mục.
chepner

Trong một cách bashism với [[: [[ $1 == -* ]].
Arthur2e5

2
Cá nhân tôi không nghĩ rằng những điều đó -sẽ là một vấn đề testở đây .. POSIX đưa ra định nghĩa về ý nghĩa theo số lượng đối số. Vì không có tùy chọn nào có hai đối số, nên sẽ an toàn khi viết nó ở dạng thô.
Arthur2e5

@ Arthur2e5 - bạn nói đúng - chúng không phải là vấn đề - và rất có thể không có vấn đề gì cả. nó vẫn là một cách kỳ lạ để làm điều đó - nó không phù hợp lắm. những gì [[ : [[làm gì?
mikeerv

1
@mikeerv Vâng, bạn nên xem trang web (nếu bạn đang đọc trang này từ nơi khác) .. Nhận xét của tôi giống như 'với START_CODE [[END_CODE: START_CODE [[$ 1 == - *]] END_CODE'. Đầu tiên [[chỉ là tên cú pháp và dấu hai chấm chỉ là dấu chấm câu.
Arthur2e5

11

Điều này sẽ lấy một chuỗi con $1từ 0 đến ký tự 1. Vì vậy, bạn sẽ nhận được ký tự đầu tiên và chỉ ký tự đầu tiên của chuỗi.

Từ trang bash3,2 người đàn ông:

  ${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

Nó đang thử nghiệm rằng ký tự đầu tiên của đối số đầu tiên $1là dấu gạch ngang -.

1: 0: 1 là các giá trị cho việc mở rộng tham số : ${parameter:offset:length}.

Điêu đo co nghia la:

  • Tên: tham số có tên 1, nghĩa là:$1
  • Bắt đầu: từ ký tự đầu tiên 0(được đánh số từ 0).
  • Độ dài: cho 1 ký tự.

Tóm lại: ký tự đầu tiên của tham số vị trí đầu tiên $1.
Sự mở rộng tham số đó có sẵn trong ksh, bash, zsh (ít nhất).


Nếu bạn muốn thay đổi dòng thử nghiệm:

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

Tùy chọn Bash

Các giải pháp bash an toàn hơn có thể là:

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

An toàn hơn vì điều này không có vấn đề với trích dẫn (không có phân chia được thực hiện bên trong [[)

Tùy chọn POSIXly.

Đối với đạn pháo cũ, ít khả năng hơn, có thể được đổi thành:

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

Chỉ có trường hợp lệnh là chống lại trích dẫn sai.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.