代码在终端上手动运行但无法运行脚本

Kev*_*lza 7 bash shell-script

我创建了这个脚本来用 cron 备份我的 postgresql 数据库:

备份文件

#!/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
Run Code Online (Sandbox Code Playgroud)

如果我将此代码复制并粘贴到终端上,它可以正常工作,但是如果我尝试运行该脚本,则会出现此错误:

user@dental:~/scripts$ ./backup.sh
export: bad interpreter: no such file or directory

我的脚本有问题吗?或者它说的是错误的解释器?

ilk*_*chu 11

如果第一行仅以 CR(而不是 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
Run Code Online (Sandbox Code Playgroud)

发生的情况是内核寻找一个名为 的解释器程序/bin/bash\rexport,但没有找到,并抛出一个错误。Bash 打印带有文件名的错误消息

bash: ./test.sh: /bin/bash\rexport: bad interpreter: No such file or directory
Run Code Online (Sandbox Code Playgroud)

但由于回车将输出移回行首,您只能看到

export: bad interpreter: No such file or directory
Run Code Online (Sandbox Code Playgroud)

所以问题似乎出在行尾上。

请注意,使用 DOS 风格的 CRLF 行结束,结果是不同的,因为现在有一个 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
Run Code Online (Sandbox Code Playgroud)

虽然我不知道为什么 bash 这次似乎在输出中引用了 CR ^M


IIRC 作为行尾的唯一 CR 是旧 Mac 系统的残余,dos2unix默认情况下似乎没有修复它。您需要使用mac2unixdos2unix -c mac

如果您碰巧混合了所有样式并且在任何其他意义上不需要 CR,这样的事情也应该将所有 CR 或 CRLF 转换为 Unix 样式的 LF 行尾。

sed 's/\r/\n/g;s/\n$//' backup.sh
Run Code Online (Sandbox Code Playgroud)