/usr/bin/env: ‘ruby’: 没有那个文件或目录

当crontab尝试执行脚本时:
@reboot sh /home/username/unicorn_start.sh > /home/username/unicorn_start.out 2>&1

它为我创建了一个带有以下内容的日志文件:/usr/bin/env: ‘ruby’: No such file or directory
这是我在unicorn_start.sh中的内容:
#!/bin/bash

PATH="$PATH:/usr/local/rvm/gems/ruby-1.9.2-p180/bin"

/etc/init.d/unicorn_myapp start

如果我手动执行unicorn_myappunicorn_start.sh,一切都正常。据我了解,我需要将一个额外的路径添加到$PATH变量中。怎么做呢?提前感谢。
编辑:

unicorn_init.sh:

#!/bin/sh
### BEGIN INIT INFO
# Provides:          unicorn
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Manage unicorn server
# Description:       Start, stop, restart unicorn server for a specific application.
### END INIT INFO
set -e

# Feel free to change any of the following variables for your app:
TIMEOUT=${TIMEOUT-60}
APP_ROOT=/home/username/appname
PID=$APP_ROOT/tmp/pids/unicorn.pid
CMD="cd $APP_ROOT; bundle exec unicorn -D -c $APP_ROOT/config/unicorn.rb -E production"
AS_USER=root
set -u

OLD_PIN="$PID.oldbin"

sig () {
  test -s "$PID" && kill -$1 `cat $PID`
}

oldsig () {
  test -s $OLD_PIN && kill -$1 `cat $OLD_PIN`
}

run () {
  if [ "$(id -un)" = "$AS_USER" ]; then
    eval $1
  else
    su -c "$1" - $AS_USER
  fi
}

case "$1" in
start)
  sig 0 && echo >&2 "Already running" && exit 0
  run "$CMD"
  ;;
stop)
  sig QUIT && exit 0
  echo >&2 "Not running"
  ;;
force-stop)
  sig TERM && exit 0
  echo >&2 "Not running"
  ;;
restart|reload)
  sig HUP && echo reloaded OK && exit 0
  echo >&2 "Couldn't reload, starting '$CMD' instead"
  run "$CMD"
  ;;
upgrade)
  if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
  then
    n=$TIMEOUT
    while test -s $OLD_PIN && test $n -ge 0
    do
      printf '.' && sleep 1 && n=$(( $n - 1 ))
    done
    echo

    if test $n -lt 0 && test -s $OLD_PIN
    then
      echo >&2 "$OLD_PIN still exists after $TIMEOUT seconds"
      exit 1
    fi
    exit 0
  fi
  echo >&2 "Couldn't upgrade, starting '$CMD' instead"
  run "$CMD"
  ;;
reopen-logs)
  sig USR1
  ;;
*)
  echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"
  exit 1
  ;;
esac

你想启动一个守护进程(假设是从 /etc/init.d/ 目录下)吗?在这种情况下,你应该将其作为一个服务来启动,而不是使用 cron。请参考此链接:https://askubuntu.com/questions/19320/how-to-enable-or-disable-services - Melebius
当我以sudo service unicorn_appname start的形式启动时,它给出一个错误:/etc/init.d/unicorn_appname: 1: eval: bundle: not found - Alex Zakruzhetskyi
你应该把代码展示给我们看,位于/etc/init.d/unicorn_myapp。到目前为止,你发布的代码中没有包含对/usr/bin/env的调用。 - Melebius
unicorn_myapp 是一个符号链接,指向位于 Rails 项目的 app/config 文件夹中的 unicorn_init.sh。如果你需要 unicorn_init.sh 的内容,我会在帖子中添加它。 - Alex Zakruzhetskyi
3个回答

默认的PATH crontab正在使用的是"只有" /usr/bin:/bin,但是你可以进行调整。
不要将那个脚本中的内容写入,而是直接添加到crontab命令中。
@reboot PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/rvm/gems/ruby-1.9.2-p180/bin"; /etc/init.d/unicorn_myapp start > /home/username/unicorn_start.out 2>&1

你还可以在每个cronjob上面添加路径变量,这样它就适用于你放在其中的每个任务。
 PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/rvm/gems/ruby-1.9.2-p180/bin"
 #
 #
 * * * * * myjob.sh
 @reboot /home/username/unicorn_start.sh > /home/username/unicorn_start.out 2>&1

仍然,它给我同样的错误:/usr/bin/env: ‘ruby’: 没有这个文件或目录 - Alex Zakruzhetskyi
你试过哪个解决方案? - Ziazis
你写的第一个。编辑:尝试了第二个解决方案,但结果没有改变。 - Alex Zakruzhetskyi
1听起来更像是你的Ruby脚本的问题,而不是cronjob的问题。你可以尝试使用一个简单的“echo $PATH”而不是你的脚本,看一下PATH变量包含什么,或者创建一个Hello World的Ruby脚本,并尝试将其输出导入到一个文件中。 - Ziazis
echo $PATH 输出的结果是:/root/bin:/root/.local/bin:/root/.rbenv/plugins/ruby-build/bin:/root/.rbenv/shims:/root/.rbenv/bin:/usr/local/rvm/gems/ruby-1.9.2-p180/bin:/usr/local/rvm/gems/ruby-1.9.2-p180@global/bin:/usr/local/rvm/rubies/ruby-1.9.2-p180/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/local/rvm/gems/ruby-1.9.2-p180/bin:/snap/bin:/usr/local/rvm/bin - Alex Zakruzhetskyi
我指的是将其放入您的 crontab 而不是您的 unicorn 脚本中。例如,@reboot echo $PATH > /tmp/crontab.path,重新启动并查看在重新启动期间实际使用的 PATH。如果您使用了第二个选项,那么它应该是已设置的路径。 - Ziazis
它给了我:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/rvm/gems/ruby-1.9.2-p180/bin - Alex Zakruzhetskyi
让我们在聊天中继续这个讨论。 - Ziazis

如果您使用which命令,您应该能够看到您的ruby可执行文件所在的位置,例如:
which ruby

/usr/bin/ruby

你可以将该路径添加到$PATH变量中,以便直接访问crontab(不确定最佳做法是什么,但在过去的经验中有效)。

我遇到了同样的问题,以下是详细信息:

系统上已经安装了Ruby。

which ruby命令返回/usr/local/bin/ruby,但是如果尝试从cron运行任何脚本,就会抛出错误/usr/bin/env: ‘ruby’: No such file or directory

稍微调查了一下发现,即使/usr/local/bin/$PATH环境变量中,env还是尝试从/usr/bin/ruby加载ruby二进制文件。因此,我创建了一个软链接。

ln -s /usr/local/bin/ruby /usr/bin/ruby

现在脚本也可以从cron中运行了。