Lỗi không tìm thấy lệnh trong gán biến Bash


521

Tôi có kịch bản này được gọi là test.sh:

#!/bin/bash
STR = "Hello World"
echo $STR

Khi tôi chạy sh test.shtôi nhận được điều này:

test.sh: line 2: STR: command not found

Tôi đang làm gì sai? Tôi nhìn vào các hướng dẫn viết kịch bản bash cực kỳ cơ bản / người mới bắt đầu trực tuyến và đây là cách họ nói để khai báo các biến ... Vì vậy, tôi không chắc mình đang làm gì sai.

Tôi đang dùng Ubuntu Server 9.10. Và vâng, bash nằm ở /bin/bash.


49
Tôi rất vui vì bạn đã đặt câu hỏi, bạn không phải là người duy nhất ngoài kia!
xay con khỉ đột

6
Cảm ơn đã hỏi câu hỏi đó. Đây không phải là một câu hỏi để bối rối. Tôi đang làm việc đêm khuya trong văn phòng và không có chuyên gia Bash xung quanh tôi để trả lời điều này.
Adway Lele

3
Những ngày này (gần bảy năm sau!) Có một kẻ nói dối / phân tích FOSS được gọi là shellcheck sẽ tự động phát hiện điều này và các vấn đề cú pháp phổ biến khác. Nó có thể được sử dụng trực tuyến hoặc cài đặt ngoại tuyến và tích hợp trong trình chỉnh sửa của bạn.
anh chàng kia


Tôi muốn khuyên bạn nên sử dụng: #!/usr/bin/env bashthay vì đưa trực tiếp #!/bin/bashtrừ khi bạn hoàn toàn chắc chắn của bạn bashlà ở /binvì câu trả lời này: stackoverflow.com/a/21613044/3589567
Alejandro Blasco

Câu trả lời:


929

Bạn không thể có khoảng trắng xung quanh dấu '=' của mình.

Khi bạn viết:

STR = "foo"

bash cố gắng chạy một lệnh có tên là STR với 2 đối số (chuỗi '=' và 'foo')

Khi bạn viết:

STR =foo

bash cố chạy một lệnh có tên là STR với 1 đối số (chuỗi '= foo')

Khi bạn viết:

STR= foo

bash cố gắng chạy lệnh foo với STR được đặt thành chuỗi rỗng trong môi trường của nó.

Tôi không chắc chắn nếu điều này giúp làm rõ hoặc nếu nó chỉ là sự xáo trộn, nhưng lưu ý rằng:

  1. lệnh đầu tiên chính xác tương đương với : STR "=" "foo",
  2. cái thứ hai giống như STR "=foo",
  3. và cuối cùng là tương đương với STR="" foo.

Phần có liên quan của thông số ngôn ngữ sh, phần 2.9.1 nêu:

"Lệnh đơn giản" là một chuỗi các phép gán và chuyển hướng tùy chọn, trong bất kỳ chuỗi nào, tùy ý theo sau bởi các từ và chuyển hướng, được chấm dứt bởi một toán tử điều khiển.

Trong bối cảnh đó, a wordlà lệnh mà bash sẽ chạy. Bất kỳ chuỗi nào chứa =(ở bất kỳ vị trí nào khác ngoài đầu chuỗi) không phải là chuyển hướng đều là một phép gán biến, trong khi bất kỳ chuỗi nào không phải là chuyển hướng và không chứa =là một lệnh. Trong STR = "foo", STRkhông phải là một sự phân công biến.


2
Nếu bạn có một biến có tên là "-", lỗi tương tự sẽ xảy ra. Trong trường hợp đó, giải pháp là xóa "-"
chomp

1
chomp @ Trong quy tắc 7b của phần 2.10.10 của pubs.opengroup.org/onlinepub/9699919799 "Nếu tất cả các ký tự đứng trước '=' tạo thành một tên hợp lệ (xem Tên XBD), mã thông báo ASSIGNMENT_WORD sẽ được trả lại." Theo liên kết đến phần 3.231 của pubs.opengroup.org/onlinepub/9699919799 , chúng tôi tìm thấy "Trong ngôn ngữ lệnh shell, một từ chỉ bao gồm dấu gạch dưới, chữ số và bảng chữ cái từ bộ ký tự di động. Ký tự đầu tiên của tên là không phải là một chữ số. ". Vì vậy, từ FOO-BAR=quxnày không phải là một biến gán vì FOO-BARkhông phải là một tên hợp lệ.
William Pursell

2
Tôi đang cung cấp một tiền thưởng để thưởng cho lời giải thích rõ ràng này cho một vấn đề luôn luôn phổ biến cho người mới bắt đầu (tốt, và cũng có thể tìm thấy nó nhanh hơn bất cứ khi nào tôi muốn liên kết nó: D). Cảm ơn đã làm cho mọi thứ này dễ dàng!
fedorqui 'SO ngừng làm hại'

1
@fedorqui Cảm ơn! Tôi không hoàn toàn tin rằng đây là một lời giải thích rõ ràng và tôi thường tự hỏi liệu nó có thể được làm đơn giản hơn không.
William Pursell

159

Thả các khoảng trống xung quanh =dấu hiệu:

#!/bin/bash 
STR="Hello World" 
echo $STR 

9
Mặc dù vậy, điều này thật buồn cười, cũng set foo = barlà một lỗi phổ biến trong các tệp bó của Windows và cũng có ngôn ngữ bó bị chế giễu ;-)
Joey

Cảm ơn @joey. Tôi đã bị mắc kẹt trong việc viết một kịch bản shell trong đó tôi đang khởi tạo các biến có khoảng trắng sau "=". Bạn đã cứu ngày của tôi
Lalit Rao

Tại sao bash không chấp nhận số trong trường bên trái? như 3 = "Hello World", nó phàn nàn về lệnh không được tìm thấy
Freedo

6

Trong chế độ tương tác, mọi thứ đều ổn:

$ str="Hello World"
$ echo $str
Hello World

Rõ ràng (!) Như Julian nói, không có không gian xung quanh =. Trong trường hợp có bất kỳ khoảng trống nào xung quanh =thì trong chế độ tương tác, nó sẽ báo lỗi như

Không tìm thấy lệnh 'str'


2
Nhưng lưu ý rằng OP đã nói STR = "Hello World", vì vậy câu trả lời này không áp dụng ở đây.
fedorqui 'SO ngừng làm hại'

@Arkapravo ý nghĩa của chế độ tương tác là gì, nó có liên quan gì đến $nhãn hiệu không
Kasun Siyambalapitiya

@KasunSiyambalapitiya bằng "chế độ tương tác", ông có nghĩa là gõ các lệnh đó trong thiết bị đầu cuối thực tế, không phải vào một tập lệnh.
numbermaniac

5

Tôi biết điều này đã được trả lời với một câu trả lời chất lượng rất cao. Nhưng, trong ngắn hạn, bạn không thể có không gian.

#!/bin/bash
STR = "Hello World"
echo $STR

Không hoạt động vì các khoảng trống xung quanh dấu bằng. Nếu bạn định chạy ...

#!/bin/bash
STR="Hello World"
echo $STR

Nó sẽ làm việc


2

Khi bạn xác định bất kỳ biến nào thì bạn không phải đặt thêm bất kỳ khoảng trắng nào.

Ví dụ

name = "Stack Overflow"  
// it is not valid, you will get an error saying- "Command not found"

Vì vậy, loại bỏ không gian:

name="Stack Overflow" 

và nó sẽ hoạt động tốt.

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.