Vấn đề với tập lệnh Bash: 'khai báo: không tìm thấy'


23

Tôi đã có một kịch bản đang chạy tốt nhưng khi tôi chạy nó ngày hôm nay, nó nói declare: not found. Tôi đang sử dụng bash shell và đường dẫn khi bắt đầu tập lệnh là chính xác.

Hai dòng được gắn cờ trong tập lệnh của tôi như sau:

declare -a RESPONSE
RESPONSE=($RESULT)

Nó cũng nói (là bất ngờ nhưng tôi đoán rằng điều đó sẽ xảy ra vì lỗi đầu tiên. Điểm đáng nói là khi tôi gõ vào khai báo trực tiếp hoạt động tốt.

declare | grep USER trình diễn

USER=ashfame
USERNAME=ashfame
           values="$SVN_BASH_USERNAME";

Vì vậy, những gì sai ở đây?

Câu trả lời:


27

Bạn đang sử dụng shthay vì bash? sh(được liên kết đến dash) không hỗ trợ declaretừ khóa, cũng như cú pháp

VAR=(list) 

để khởi tạo mảng.


Dòng shebang của tôi là #!/bin/bashduy nhất. Ý bạn là làm thế nào tôi thực hiện nó? Tôi chỉ cố gắng thực hiện nó như ./script.shvà nó làm việc. Nhưng nó không hoạt động như script.shhoặc sh script.shtôi khá chắc chắn rằng tôi đã từng chỉ sử dụng hai phương thức sau trong khi tôi tạo nó một tuần trước. Điều gì có thể giải thích điều đó?
Ashfame

@Ashfame: có thể một tuần trước nó đã bỏ lỡ các tính năng dành riêng cho bash bạn có bây giờ, vì vậy nó cũng hoạt động với sh script.sh
enzotib

Không, ý tôi là chính xác kịch bản này được sử dụng để làm việc một hoặc hai tuần trước. Hoặc bạn có nghĩa là một số cập nhật có thể đã thực hiện một sự thay đổi?
Ashfame

@Ashfame: Tôi không biết, kịch bản này, như bạn hiển thị bây giờ, không thể hoạt động với sh script.sh.
enzotib

11

Tôi nghi ngờ rằng dòng "shebang" của bạn (dòng đầu tiên tùy chọn của tệp) là tham chiếu shthay vì bash. Nó nên

#!/bin/bash

cho các tập lệnh bash. Nếu dòng đầu tiên của tập lệnh của bạn là

#!/bin/sh

sau đó sẽ chỉ ra rằng một vỏ tương thích nghiêm ngặt sẽ được sử dụng; trong trường hợp Ubuntu, dashđược sử dụng. Trong nhiều bản phân phối khác, điều này không gây ra vấn đề gì, vì chúng liên kết /bin/shđến /bin/bash; tuy nhiên ubfox liên kết đến /bin/dashđể cho phép các tập lệnh hệ thống chạy nhanh hơn.

Nội dung declarelà một trong bashnhiều phần mở rộng cho đặc tả tập lệnh shell Bourne; dashchỉ thực hiện đặc tả mà không có phần mở rộng.


Dòng #!/bin/bash
shebang

@Ashfame: bạn đang chạy tập lệnh như thế nào? Nếu bạn đang gọi nó bằng cách chỉ cần gõ tên của tập lệnh, dòng shebang sẽ xác định trình thông dịch nào chạy nó. Tuy nhiên, nếu bạn gọi nó một cách rõ ràng sh thescript.sh, shshell - tức là dashsẽ diễn giải nó.
trực giác

1
@intuited Tôi đã chạy nó qua sh script.sh. Tôi hiểu những gì bạn nói, nhưng tôi đã đọc ở đâu đó rằng với phương pháp này, bashsẽ diễn giải nó. Tại sao có dashđược vai trò ở đây? Có phải chỉ với Ubuntu? Có thể là những gì tôi đọc được cho linux nói chung.
Ashfame

2
@Ashfame với sh scriptbạn đang chạy lệnh shvới đối số script, điều này làm cho sh đọc và thực thi các lệnh trong tệp đó. Shebang không được đọc bởi sh, nó bắt đầu bằng a #, vì vậy nó được coi là một nhận xét. Thay vào đó ./script, nếu bạn chạy , thì kernel sẽ đọc shebang, trong trường hợp của bạn là #!/bin/bash, và do đó, nó thực thi/bin/bash ./script
geirha

@geirha vâng, đó là cách tôi biết nó hoạt động nhưng @intuited đề cập đến việc dashsẽ được sử dụng, vì vậy tôi cần làm rõ nó
Ashfame

3

Cách tái tạo lỗi trên:

Tôi đang sử dụng Ubuntu 14.04 64 bit. Đặt mã này vào một tệp:

#!/bin/sh 
declare -i FOOBAR=12; 
echo $FOOBAR; 

Chạy nó như thế này:

el@apollo:~$ ./06.sh 
./test.sh: 2: ./test.sh: declare: not found

Để khắc phục, thay vào đó, hãy làm điều này:

#!/bin/bash
declare -i FOOBAR=12;
echo $FOOBAR;

Bản in:

el@apollo:~$ ./06.sh 
12

1

Tôi có cùng một vấn đề, và sau đó tôi nhớ rằng bạn cần gán quyền cho phép để thực thi tập lệnh shell.

Thay đổi quyền của tập lệnh, ví dụ:

chmod 755 script.sh

1

/bin/bashThay vào đó, hãy thử chạy tập lệnh của bạn bằng dòng lệnh if sh(:

Thay vì :

    sh script.sh

Thử :

    / bin / bash script.sh

1

Trên Ubuntu, bạn có thể có một tập lệnh đang thực thi các tập lệnh khác trong tập lệnh mà tôi đã chạy vào.

some_dir/  
        | main.sh  
        | shhh.sh

#!/bin/bash -e

echo "file? $0"
# file? ./main.sh

echo "shell? $SHELL" 
# shell? /bin/bash

# sh shhh.sh
# file? shhh.sh
# shell? /bin/bash
# shhh.sh: 5: shhh.sh: declare: not found

$SHELL shhh.sh
# file? shhh.sh
# shell? /bin/bash
# foo? bar

#!/bin/bash -e

echo "file? $0"
# shhh.sh

echo "shell? $SHELL"
# shell? /bin/bash

declare foo="bar"

echo "foo? $foo"

Thay đổi tất cả sh some_script.shđể $SHELL some_script.shsửa nó.

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.