【问题标题】:command not found when runng bash script as user apache以用户 apache 身份运行 bash 脚本时找不到命令
【发布时间】:2012-07-17 15:59:10
【问题描述】:

我正在尝试以 apache 用户身份运行 bash 脚本。它抛出了以下内容

[apache@denison public]$ ll
total 32
drwxr-xr-x 2 apache apache 4096 Jul 17 08:14 css
-rw-r--r-- 1 apache apache 4820 Jul 17 10:04 h3111142_58_2012-07-17_16-03-58.php
-rwxrwxrwx 1 apache apache   95 Jul 17 10:04 h31111.bash
drwxr-xr-x 2 apache apache 4096 Jul 17 08:14 images
-rw-r--r-- 1 apache apache  754 Jul 17 08:13 index.php
drwxr-xr-x 2 apache apache 4096 Jul 17 08:14 javascript
drwxr-xr-x 5 apache apache 4096 Jul 17 08:14 jquery-ui-1.8.21.custom
[apache@denison public]$ bash h31111.bash
: command not found :

文件内容为:

#!/bin/bash

/usr/bin/php /opt/eposdatatransfer/public/h3111142_58_2012-07-17_16-03-58.php 

php脚本运行良好,下面是结果

[apache@denison public]$ /bin/bash h31111.bash
: command not found:
[apache@denison public]$ chmod +x h31111.bash
[apache@denison public]$ ./h31111.bash
./h31111.bash: Command not found.
[apache@denison public]$ php h3111142_58_2012-07-17_16-03-58.php

创建文件:

$batchFile = $this->session->username . "_" . $index . "_" . $date . ".sh";
            $handle = fopen($batchFile, 'w');
            $data = "#!/bin/bash
/usr/bin/php /opt/eposdatatransfer/public/$file 
";
            /*
rm -rf /opt/eposdatatransfer/public/$file
rm -rf /opt/eposdatatransfer/public/$batchFile*";*/
            fwrite($handle, $data);
            fclose($handle);

batchfile 是 bash 脚本,file 是 php 文件。这些会根据 webapp 中的用户输入自动创建。我的 webapp 在 linux 上运行。

【问题讨论】:

    标签: linux apache bash


    【解决方案1】:

    我猜你是从 Windows 机器上传脚本的,并没有从行尾去掉回车符。这会导致 #!机制(大多数脚本的第一行)失败,因为它搜索很少存在的 #!/some/interpreter^M。

    如果有回车符,您可以使用 fromdos 或:

    tr -d '\015' < /path/to/script > /tmp/script; chmod 755 /tmp/script; mv /tmp/script /path/to/script
    

    【讨论】:

    • 我没有在 Windows 中创建它们。它是由我在 linux 上运行的网络应用程序创建的。 $batchFile = $this-&gt;session-&gt;username . "_" . $index . "_" . $date . ".sh"; $handle = fopen($batchFile, 'w'); $data = "#!/bin/bash /usr/bin/php /opt/eposdatatransfer/public/$file "; /* rm -rf /opt/eposdatatransfer/public/$file rm -rf /opt/eposdatatransfer/public/$batchFile*";*/ fwrite($handle, $data); fclose($handle);
    【解决方案2】:

    如果您尝试运行脚本会发生什么

     $ /bin/bash h31111.bash
    

    试试这个(假设你的脚本文件名为“h31111.bash”):

     $ chmod +x h31111.bash
    

    然后运行它

     $ ./h31111.bash
    

    您还确定您的php 命令路径正确吗? which php 报告什么?

    --

    正如@jordanm 根据我建议您运行的file 命令的输出正确建议的那样,您需要对您的文件运行dos2unix 命令。如果你没有安装这个tr -d '\r' 也可以。即,

     $ tr -d '\r' h31111.bash > tmp.bash
     $ mv tmp.bash h31111.bash
    

    你应该准备好了。

    在某些版本的 Ubuntu 下,不会安装这些实用程序(例如 dos2unix),有关这方面的信息,请参阅 this page

    【讨论】:

    • 见上面我已经更新了同样的问题。它运行运行 php 脚本的 bash 脚本。但是,如果我通过网络服务器或批处理队列运行它,它根本不起作用
    • [apache@denison public]$ ls -l /bin/bash -rwxr-xr-x 1 root root 801528 May 13 2011 /bin/bash [apache@denison public]$ which bash /bin/bash
    • [apache@denison public]$ which php /usr/bin/php [apache@denison public]$
    • @sharif 好的,还有一个命令file h31111.bash 给出什么输出?
    • cat -vet h31111.bash 显示什么 - 文件中是否有一些奇怪/意外的字符?我想知道那个空白行是否隐藏了一些东西......或者可能是行尾问题......
    【解决方案3】:

    在我看来问题出在你的 $PATH 上。系统上的某些用户的 $PATH 中会包含 .(当前目录),而其他用户则不会。如果输入 ./h31111.bash 有效,那么这就是你的问题。您可以使用相对或绝对路径指定文件,也可以添加 .到该用户的 $PATH 但永远不要为 root 这样做

    【讨论】:

    • 在 UNIX/Linux 中,变量 $PATH 包含要在其中查找可执行文件的目录列表,就像 Windows 中的 %PATH% 一样。如果您键入没有路径名的可执行文件(二进制文件或脚本)的名称,它将在所有这些位置查找它。并且该变量可以(并且通常是)针对不同的用户进行不同的设置。如果您键入一个可执行文件的名称,而该文件的路径不在这些位置之一,则 shell 无法找到它,即使它在当前目录 (.) 中,如果 .不在 $PATH 中。出于安全原因,许多用户在 $PATH 中没有它。
    【解决方案4】:

    既然你不确定哪里出了问题,让我们试着找出答案。

    首先,你能执行程序吗?

    ./h31111.bash
    

    这应该相当于调用它:

    /bin/bash h31111.bash
    

    如果上面给出的错误消息与脚本内容相同,则可能是脚本内容有问题。要找出 bash 脚本中哪里出了问题,您可以使用 set -xset -v

    set -x 将向您展示扩展 set -v 将在他们阅读之前向您显示这些行

    因此,您可以将脚本内容更改为以下内容:

    #!/bin/bash
    set -x
    set -v
    /usr/bin/php /opt/eposdatatransfer/public/h3111142_58_2012-07-17_16-03-58.php
    

    您可能只能通过经验了解到的另一种可能性是文件处于 MSDOS 模式(即,具有 CR LF 而不仅仅是 LF)。如果您仍在使用 FTP(而不是 SFTP)并处于 ASCII 模式,这通常会发生。您可以将传输模式设置为二进制并让一切顺利进行。如果没有,您有几个选择。 任何以下行都应该有效:

    dos2unix /path/to/your/file
    sed -i 's/\r//g' /path/to/your/file
    tr -d '\r' < /path/to/your/file > /path/to/temp/file && mv /path/to/temp/file /path/to/your/file
    

    在 Vim 中,您可以执行 :set ff=unix 并保存文件以更改格式。

    让我们看看你在 PHP 中有什么:

    $handle = fopen($batchFile, 'w');
    $data = "#!/bin/bash
    /usr/bin/php /opt/eposdatatransfer/public/$file 
    ";
    

    由于您有一个多行字符串,因此嵌入的 CR LF 字符将取决于您的 PHP 文件是 Windows 还是 Unix 格式。您可以将该文件切换为 Windows 格式,就可以了。但这似乎在未来很容易被打破,所以我会选择一些不那么不稳定的东西:

    $handle = fopen($batchFile, 'w');
    fwrite($handle, "#!/bin/bash\n");
    fwrite($handle, "/usr/bin/php /opt/eposdatatransfer/public/$file\n");
    fclose($handle);
    

    【讨论】:

    • [apache@denison public]$ /bin/bash h31111.bash : invalid optione 2: set: - set: usage: set [--abefhkmnptuvxBCHP] [-o option] [arg ...] : invalid optione 3: set: - set: usage: set [--abefhkmnptuvxBCHP] [-o option] [arg ...]
    • 这个脚本是在我的网络应用程序中创建的,它在不同的服务器上运行良好。在生产服务器上它没有,我得到了我提到的错误
    • 如果您在 ASCII 模式下使用 FTP,则会导致添加回车符。帖子已编辑以提供更多选择。
    • 我将如何在 php 中执行此操作?我的 webapp 正在根据变量等自动创建此文件。
    猜你喜欢
    • 2019-02-24
    • 1970-01-01
    • 2016-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-08
    • 1970-01-01
    • 2017-08-10
    相关资源
    最近更新 更多