Mã hoạt động thủ công trên thiết bị đầu cuối nhưng không thể chạy tập lệnh


7

Tôi đã tạo tập lệnh này để sao lưu cơ sở dữ liệu postgresql của mình bằng cron:

sao lưu

#!/bin/bash
export PGUSER="user"
export PGPASSWORD="pass"
FECHA_ACTUAL=`date +%Y-%m-%d`
HORA_ACTUAL=`date +%H:%M`
ARCH_RESP=$FECHA_ACTUAL-$HORA_ACTUAL
pg_dump -O -Fc mydb -h localhost > /home/user/backups/backup_$ARCH_RESP.sql
find /home/user/backups/ -name '*.sql' -mtime +2 -exec rm -f {} \;
unset PGUSER
unset PGPASSWORD

Nếu tôi sao chép và dán mã này vào thiết bị đầu cuối thì nó hoạt động tốt, nhưng nếu tôi cố chạy tập lệnh, tôi gặp lỗi này:

user @ nha: ~ / scripts $ ./backup.sh
export: trình thông dịch xấu: không có tệp hoặc thư mục như vậy

Có điều gì sai với kịch bản của tôi? Hay là nó thông dịch sai như nó nói?


1
Sản lượng của type -a bashcái gì?
heemayl

Vui lòng chỉnh sửa câu hỏi và gửi đầu ra của lệnh này : head -n 1 backup.sh | od -c.
terdon

1
Tệp của bạn có thể không ở định dạng Linux. nếu đầu ra của [tệp <your-file>] cho biết "văn bản ASCII, với các đầu cuối dòng CRLF", thì hãy thay đổi định dạng bằng dos2unix.
tonioc

Câu trả lời:


11

Tôi có thể gặp lỗi tương tự nếu dòng đầu tiên bị chấm dứt chỉ với CR (thay vì LF):

$ echo -en '#!/bin/bash\rexport foo=bar\n' > test.sh
$ chmod +x test.sh
$ ./test.sh
export: bad interpreter: No such file or directory

Điều gì xảy ra là kernel tìm kiếm một chương trình thông dịch được gọi /bin/bash\rexport, không tìm thấy nó và làm giảm lỗi. Bash in một thông báo lỗi với tên của tệp

bash: ./test.sh: /bin/bash\rexport: bad interpreter: No such file or directory

nhưng vì trở về vận chuyển di chuyển đầu ra trở lại phía trước của dòng, bạn chỉ thấy

export: bad interpreter: No such file or directory

Vì vậy, vấn đề dường như là với các kết thúc dòng.

Lưu ý rằng với một kết thúc dòng CRLF theo kiểu DOS, kết quả sẽ khác, vì bây giờ có một kết thúc LF.

$ echo -en '#!/bin/bash\r\nexport foo=bar\n' > test.sh
$ ./test.sh    
bash: ./test.sh: /bin/bash^M: bad interpreter: No such file or directory

Mặc dù tôi không biết tại sao bash dường như trích dẫn CR về đầu ra như ^Mlần này.


IIRC CR đơn độc như một dòng kết thúc là phần còn lại của các hệ thống Mac cũ và dos2unixdường như không sửa nó theo mặc định. Bạn cần sử dụng mac2unixhoặc dos2unix -c mac.

Một cái gì đó như thế này cũng sẽ biến tất cả CR hoặc CRLF thành các kết thúc dòng LF theo phong cách Unix, nếu bạn tình cờ có tất cả các kiểu trộn lẫn và không cần CR theo bất kỳ ý nghĩa nào khác.

sed 's/\r/\n/g;s/\n$//' backup.sh

Cảm ơn nó đã làm việc với sed 's / \ r / \ n / g; s / \ n $ //' backup.sh
Elros Romeo

Tôi đã làm gì sai khi tôi tạo sh của mình?
Elros Romeo

@ElrosRomeo Điều đó khó nói hơn, vì chúng tôi không biết bạn đã tạo ra nó như thế nào. Một số trình soạn thảo có thể chọn kiểu kết thúc dòng, vì vậy nó có thể chỉ là cấu hình sai trên trình chỉnh sửa.
ilkkachu

Cảm ơn, tôi đã viết nó bằng mousepad và lưu nó với phần mở rộng sh, sau đó tôi chỉnh sửa tệp bằng 777
Elros Romeo
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.