/ usr / bin / env:php:没有这样的文件或目录


9

我想使用.sh脚本来部署我的应用程序。该脚本在我的家庭服务器(Ubuntu 15.10服务器)上,标记为可执行文件。使用ssh可以访问此脚本,使用教程,我已经设置了运行该脚本的ssh登录。因此,基本上我只是调用ssh deployer@XXX.com someArguments它,并someArguments以参数的形式运行我的脚本。用户的deployeruid = 0,因此基本上是uid = 0 root(将来会对此进行更改,我将其设置为仅消除权限问题,直到可以正常工作为止)。

这就是事情变得棘手的地方。该脚本/usr/bin/env: php: No such file or directory在命令中报告/bin/composer install(使用Composer)。我越看那个脚本,事情就越怪异。在此行之前,还调用了/bin/composer self-update/bin/composer -V,它们都可以正常运行并显示正确的输出。

我检查了以下内容:

  • /usr/bin/env php -v显示正确的PHP版本(与相同/usr/bin/php -v
  • whereis php 显示 php: /usr/bin/php /usr/local/bin/php /usr/share/man/man1/php.1.gz
  • php5-cli 已安装软件包和最新版本
  • $PATH 包含 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
  • which env 显示 /usr/bin/env

我还尝试了以下操作:

  • 直接bash deploy.sh在root用户下运行脚本(因为它与该用户相同)-完美运行而没有错误
  • 直接运行失败的命令-完美无误

所以在我看来,这是非常具体的情况,为什么此命令不起作用。我花了12个小时来调试它,但在这里没有主意。

PS:/usr/bin/env: node: No such file or directory存在bower install(使用Bower)时发生类似的错误(),但运行时(使用NPM)则不会发生类似的错误。npm install


运行sh deploy而不是bash deploy(也许是一些bashism)。您如何检查“ 以下事项 ”?我建议在脚本中检查它们,以便您可以发现最终的覆盖和环境污染。
Giacomo Catenazzi

关于“ 以下内容 ”:我将它们添加到deploy.sh脚本的开始,并且它们输出了我质疑的这些内容。但是,当我单独运行它们时,输出相同。
托马什Blatný

sh deploybash deploy两个给出相同的结果
托马什Blatný

请在此处显示该行。我建议您在调用/ usr / bin / env时,将脚本中此行的php命令替换为输出到文件以检查环境变量:/usr/bin/env > environment.txt
Oleg Bolden 2016年

Answers:


6

确保行尾和/或不可见的空格不会引起问题。

删除脚本第一行中的空格并插入新的空格,确保在按下空格时不按住CTRL。

另外,请确保您没有DOS行尾(CR + LF)。有关详细信息,请参见/programming/82726/convert-dos-line-endings-to-linux-line-endings-in-vim


我使用的是IDE,它仅自动检查(和转换)CR + LF到LF,删除BOM并关心白色字符,但是我仔细检查了一下,它看起来还不错(尽管仍然无法正常工作)。无论如何
–TomášBlatný16年

4

最简单的方法....将用户的shell更改为脚本。

/ etc / passwd

Before:
deploy:x:0:0:,,,:/root:/bin/bash

After:
deploy:x:0:0:,,,:/root:/scripts/deploy.sh

示例脚本(确保将执行位设置为chmod + x)

/scripts/deploy.sh

#!/bin/bash 
PATH=$PATH:/moo etc...
moo.sh

样品 每次都能工作!您甚至应该甚至可以使用该脚本来解决/调试您可能感觉未设置的任何env变量等问题...传递给ssh的处理参数也将起作用。

注意:始终对所有脚本,可执行文件等的路径完全合格的最佳实践。以上仅是一个示例,允许将默认路径设置为在moo文件夹中调用moo.sh;)

那很简单..感谢您的发布..

参考:/ etc / passwd格式


很好的答案,但实际上我从来没有直接在服务器上使用用户,我总是ssh在服务器上使用,并且通过进入authorized_keys,脚本被调用,然后连接结束。我authorized_keys该如何修改才能使其正常工作?
托马什Blatný

它应该工作相同。您将通过密钥进行身份验证,并且只要将外壳程序设置为将在远程服务器的/ etc / passwd文件中执行的远程帐户的脚本即可。我会在我的帖子中添加一个屏幕截图。
NotAdmin Dave

1
@Dave等不及您的书了
Burgi

感谢您的回答,它不能解决我的问题,但是对我来说是最有趣的,实际上解决了我遇到的其他问题。给你的奖金,再次感谢
托马什Blatný

4

env命令将浏览用户$PATH以查找给定名称的第一个可执行文件。因此,/usr/bin/env phpphp$PATH运行该文件的用户的任何目录中查找一个名为的可执行文件。

在您的情况下,这几乎可以肯定是因为在运行命令over时ssh,您不会启动完整的shell,也不会真正读取shell的初始化文件。您可以通过运行以下命令进行检查(注意单引号):

ssh deployer@XXX.com 'echo $PATH'

然后将输出与您获得的结果进行比较ssh deployer@XXX.com然后再运行echo $PATH。在我的系统上。例如:

$ echo $PATH
/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:

$ ssh localhost 'echo $PATH'
/usr/bin:/bin:/usr/sbin:/sbin

因此,$PATH运行脚本时可以访问的脚本与ssh deployer@XXX.com登录进行测试时可以访问的脚本不同。

无论如何,简单的解决方案是使用解释器的完整路径而不是env。无论env和完整路径有自己的优点和缺点,但是,在这种情况下,路径是安全的:

#!/usr/bin/php

ITYM“ 请注意单引号”不是“ not ”。
dave_thompson_085 '16

@ dave_thompson_085确实我做到了,谢谢。
terdon

我实际上在所有地方都使用完整路径,正如我在问题中提到的那样,该错误是 composer install命令内部报告的,我显然无法修改。还$PATH可以,就像我在问题中提到的那样,我通过将所有内容添加到脚本中并通过ssh登录远程运行来检查所有内容。另外,我无法ssh deployer@XXX.com 'echo $PATH'按照您所说的进行检查,因为我的ssh登录仅限于一个脚本,但是当我向该脚本中添加$ PATH时(如上所述),我确实进行了检查,无论如何,谢谢您的回答,并接受+ 1解释我的env东西
托马什Blatný

@TomášBlatný很好,您在某个地方使用了env,否则您将不会看到该错误。我不知道作曲家,但您可能必须将php可执行文件复制或链接到其路径中的目录。这种事情很难调试,因为彼此之间有很多事情。
terdon

没错,env实际上是在作曲家内部称为。但这并不能解决问题,为什么有些作曲家调用可以通过,而有些则不能。但是,我将通过研究其代码进一步对此进行调查。感谢您的时间
托马什Blatný

2

是否可能bash需要重置其哈希表?

如果是这样,您可以尝试hash -r在脚本中添加某个位置,这将迫使Shell重新浏览$PATH,而不是依赖哈希表中的信息(可能已过时)。

必要时,hash还可以使外壳使用该-p选件记住到安装在非标准位置的可执行文件的路径,或者使该选件忘记路径-d

资料来源:

https://unix.stackexchange.com/a/86017/121251
https://stackoverflow.com/a/22543353/2146843


这并没有解决这个问题对我来说,但其良好的知识,所以我加你一个+1
托马什Blatný

1

看起来您可能需要将php添加到路径中。尝试:

vim ~/.bashrc
PATH=$PATH:/usr/local/bin/php
export PATH

您可能还需要检查php的位置,以确保路径正确。尝试:

which php

嗯,这不是问题,因为php -v输出正确的PHP版本和composer --version输出作曲家版本。如我所说,问题仅在于一个命令。
托马什Blatný

1

显然,您遇到了路径问题,因为在执行普通的ssh登录时,部署脚本无法找到路径上肯定存在的内容。

确认您遇到PATH问题的第一件事是更新您的部署脚本,以记录env或至少输出echo $PATH。我猜想您的部署脚本的调用方式,$ PATH没有按您期望的那样设置。此调试输出将确认/否认我的理论。

我看了您遵循的教程。你应该确保在更新的command=command="/bin/sh /path/to/your/script...",如果你还没有准备好,以确保你的脚本由右shell中运行。

如果您确实遇到PATH问题,则快速/肮脏的解决方法是在部署脚本的开头明确设置PATH。

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"

详细说明和更多选项...

在linux上,当命令运行时,它们会继承其父进程的环境。

当您通过SSH以普通用户身份登录时,会发生一些事情(例如运行/ etc / bashrc / etc / profile〜/ .bash_profile〜/ .bashrc等)。到那时,您可能已经通过执行export PATH="$PATH:~/mybin"这些脚本中的操作来更新了流程的环境。现在,您将来运行的所有进程都将继承您当前的环境。

运行命令而不是获取登录shell意味着该命令由ssh守护进程运行,并将继承ssh守护进程的环境...这可能与作为登录用户的环境不同。

授权密钥的手册页介绍了认证后发生的情况。关于环境:

  1. 读取〜/ .ssh / environment文件(如果存在),并且允许用户更改其环境。请参阅sshd_config(5)中的PermitUserEnvironment选项。

因此,为进程配置环境的适当位置是在~/.ssh/environment哪里~,该用户的主目录经过身份验证可以运行该命令。您还需要检查sshd_config以确保允许PermitUserEnvironment。

~/.ssh/environment 格式当然也在手册页中指定。

         This file is read into the environment at login (if it exists).
         It can only contain empty lines, comment lines (that start with
         '#'), and assignment lines of the form name=value.  The file
         should be writable only by the user; it need not be readable by
         directory becomes accessible.  This file should be writable only
         by the user, and need not be readable by anyone else.

不使用上述方法指定环境的另一种方法是使用environment="NAME=value"authorized_keys文件中的选项。有关详细信息,请参见我上面链接的手册页。


关于Without knowing exactly how you have setup your deploy script to run:在开始时的问题中,有一个链接,我如何设置它(使用~/.ssh/authorized_keys。感谢带有update命令的技巧,我尝试了它,但是很遗憾没有任何区别。但是,我将进一步研究它并尝试使用不同的外壳。请接受+1的想法
汤玛斯·布拉特尼

您是否尝试过更新部署脚本以打印出当前$ PATH?您可以发布结果吗?如果它与您的期望不符,则可以按照我在部署脚本开始时建议的那样,尝试显式设置PATH。
mattpr '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.