bash scripting: nếu các đối số bằng chuỗi này, hãy xác định một biến như chuỗi này


225

Tôi đang thực hiện một số tập lệnh bash và bây giờ tôi có một cuộc gọi biến sourcevà một mảng được gọi samples, như thế này:

source='country'
samples=(US Canada Mexico...)

vì tôi muốn mở rộng số lượng nguồn (và mỗi nguồn có mẫu riêng) tôi đã cố gắng thêm một số đối số để làm điều này. Tôi đã thử điều này:

source=""
samples=("")
if [ $1="country" ]; then
   source="country"
   samples="US Canada Mexico..."
else
   echo "try again"
fi

nhưng khi tôi chạy kịch bản của mình source countries.sh countrythì nó không hoạt động. Tôi đang làm gì sai?


2
Làm thế nào nó không hoạt động? Khi bạn chạy nó, bạn gặp lỗi hoặc thông báo "thử lại" hoặc điều gì khác?
otto ác

2
vâng, bạn có thể nghĩ "câu hỏi rất đơn giản". nhưng bạn đã suy nghĩ về điều này trong một thời gian. Vui lòng xem xét chỉnh sửa câu hỏi của bạn để bao gồm các đầu ra cần thiết và bất kỳ thông báo lỗi nào bạn nhận được. +1 để thực sự thử một cái gì đó và định dạng tốt của câu hỏi. chúc may mắn.
shellter

Tại sao mã này giống như giải pháp được đề xuất và chấp nhận? Điều đó thật khó hiểu ... Tôi đoán câu hỏi ban đầu không có khoảng trắng ngay sau dấu ngoặc mở và trước dấu ngoặc đóng của câu if?
Stef

6
@Stef nếu bạn nhìn kỹ, $1="country"so với$1 = "country"
Sẽ

Câu trả lời:


413

Đừng quên khoảng trắng:

source=""
samples=("")
if [ $1 = "country" ]; then
   source="country"
   samples="US Canada Mexico..."
else
  echo "try again"
fi

121
Tôi không thể tin rằng mình đã dành ba giờ cho việc này và chỉ là vấn đề về không gian !!!! ... THANKS @Alex
Alejandro

1
Tại sao bạn sử dụng samples="US Canada Mexico..."sau khi giới thiệu việc tạo mảng trước samples=(US Canada Mexico...)?
người dùng không xác định

10
Tôi gặp vấn đề với điều này khi biến ở bên trái là một chuỗi rỗng. Sửa là được if [ "$1" = "country" ]; then.
andrewb

8
Được rồi đó. Bash chính thức nhận được phiếu bầu của tôi vì nuôi ong ngôn ngữ lệnh lỗi thời nhất vẫn được sử dụng. Cú pháp chỉ là không trực quan nên nó đau. Thực sự không có chỗ cho nó trong năm 2016+. Các tác giả @Systemd: bạn có thể vui lòng thực hiện "xây dựng một vỏ Linux không hút" dự án tiếp theo của bạn không? Tôi sẽ ném tiền vào bạn.
masi

3
@masi đôi khi tôi nghĩ mục đích ban đầu của unix là "bảo mật công việc thông qua che khuất". nếu các công cụ này khó sử dụng, khó hiểu và nói chung là ngoài tầm với của những người chưa được đào tạo mà không có kiến ​​thức bên trong được truyền từ chủ sang padwan, thì nó sẽ đảm bảo rằng sẽ luôn có công việc cho những người "biết". triết lý này thể hiện rõ trong toàn bộ cấu trúc "RFC" và ngôn ngữ hoa mỹ được sử dụng trong các tài liệu về con người, trong khi về mặt kỹ thuật cho bạn biết cách sử dụng các công cụ, thực sự chỉ cần có để thực hiện yêu cầu ghi lại các công cụ. ít thay đổi
không đồng bộ

184

Bạn có thể sử dụng toán tử "=" hoặc "==" để so sánh chuỗi trong bash. Yếu tố quan trọng là khoảng cách trong dấu ngoặc. Phương pháp thích hợp là dành cho dấu ngoặc để chứa khoảng cách bên trong và toán tử để chứa khoảng cách xung quanh. Trong một số trường hợp, các kết hợp khác nhau hoạt động; tuy nhiên, sau đây được dự định là một ví dụ phổ quát.

if [ "$1" == "something" ]; then     ## GOOD

if [ "$1" = "something" ]; then      ## GOOD

if [ "$1"="something" ]; then        ## BAD (operator spacing)

if ["$1" == "something"]; then       ## BAD (bracket spacing)

Ngoài ra, lưu ý dấu ngoặc kép được xử lý hơi khác so với dấu ngoặc đơn ...

if [[ $a == z* ]]; then   # True if $a starts with a "z" (pattern matching).
if [[ $a == "z*" ]]; then # True if $a is equal to z* (literal matching).

if [ $a == z* ]; then     # File globbing and word splitting take place.
if [ "$a" == "z*" ]; then # True if $a is equal to z* (literal matching).

Tôi hy vọng điều đó sẽ giúp!


12

Có vẻ như bạn đang tìm cách phân tích các đối số dòng lệnh vào tập lệnh bash của bạn. Tôi đã tìm kiếm điều này gần đây bản thân mình. Tôi đã xem qua những điều sau đây mà tôi nghĩ sẽ hỗ trợ bạn trong việc phân tích các đối số:

http://rsalveti.wordpress.com/2007/04/03/bash-parsing-argument-with-getopts/

Tôi đã thêm đoạn trích dưới đây dưới dạng tl; dr

#using : after a switch variable means it requires some input (ie, t: requires something after t to validate while h requires nothing.
while getopts ht:r:p:v OPTION
do
     case $OPTION in
         h)
             usage
             exit 1
             ;;
         t)
             TEST=$OPTARG
             ;;
         r)
             SERVER=$OPTARG
             ;;
         p)
             PASSWD=$OPTARG
             ;;
         v)
             VERBOSE=1
             ;;
         ?)
             usage
             exit
             ;;
     esac
done

if [[ -z $TEST ]] || [[ -z $SERVER ]] || [[ -z $PASSWD ]]
then
     usage
     exit 1
fi

./script.sh -t kiểm tra -r máy chủ -p mật khẩu -v

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.