"builtin: not found" 当我通过 PHP passthru() 获取脚本时
"builtin: not found" when I source a script via PHP passthru()
我已经通过 https://raw.githubusercontent.com/rvm/rvm/master/binscripts/rvm-installer
安装了 RVM
我在 Ubuntu 并且我使用 Bash。
安装后,我需要能够基于 installation instructions 获取源 ~/.rvm/scripts/rvm
。
我需要通过 CLI (test.sh) 执行一个脚本来做到这一点,该脚本又调用一个 PHP 脚本 (test.php),该脚本通过 shell 命令进行采购。
一旦我这样做,我就会收到关于 builtin
:
的错误
$ ./test.sh
sh: 10: /home/housni/.rvm/scripts/rvm: builtin: not found
这是 test.sh
运行 在 Bash 上调用 test.php
#!/bin/bash
./test.php
这是test.php
#!/usr/bin/php -q
<?php
passthru('. ~/.rvm/scripts/rvm');
?>
当我直接在终端 (bash) 中键入 source ~/.rvm/scripts/rvm
并执行它时,我没有看到任何错误。
在我看来,RVM 脚本试图执行 dash
而不是 bash
,但这并不完全有意义,因为 RVM 脚本以 #!/usr/bin/env bash
开头。
知道我在 PHP 脚本中做错了什么吗?
以下是~/.rvm/scripts/rvm
的内容:
#!/usr/bin/env bash
# rvm : Ruby enVironment Manager
# https://rvm.io
# https://github.com/wayneeseguin/rvm
# partial duplication marker dkjnkjvnckbjncvbkjnvkj
# prevent from loading in sh shells
if
builtin test -n "${BASH_VERSION:-}" -o -n "${ZSH_VERSION:-}" -o -n "${KSH_VERSION:-}"
then
case "`uname`" in
(CYGWIN*) __shell_name="`\command \ps -p $$ | \command \awk 'END {print $NF}'` 2>/dev/null" ;;
(SunOS) __shell_name="`\command \ps -p $$ -o comm=`" ;;
(*) __shell_name="`\command \ps -p $$ -o ucomm=`" ;;
esac
case "$__shell_name" in
(""|dash|sh|ksh|*/dash|*/sh|*/ksh) return 0 ;; # silently stop in sh shells
esac
unset __shell_name
else
return 0
fi
# also duplicated in scripts/base
__rvm_has_opt()
{
if # pre-gnu
[[ -n "${ZSH_VERSION}" ]]
then
setopt | GREP_OPTIONS="" \command \grep "^$" >/dev/null 2>&1 || return $?
elif # mksh
[[ -n "${KSH_VERSION}" ]]
then
set +o | GREP_OPTIONS="" \command \grep "-o $" >/dev/null 2>&1 || return $?
elif # bash
[[ -n "${BASH_VERSION}" ]]
then
[[ ":$SHELLOPTS:" == *"::"* ]] || return $?
else # what is this?!
return 1
fi
}
# Do not allow sourcing RVM in `sh` - it's not supported
# return 0 to exit from sourcing this script without breaking sh
if __rvm_has_opt "posix"
then return 0
fi
# TODO: Alter the variable names to make sense
\export HOME rvm_prefix rvm_user_install_flag rvm_path
HOME="${HOME%%+(\/)}" # Remove trailing slashes if they exist on HOME
[[ -n "${rvm_stored_umask:-}" ]] || export rvm_stored_umask=$(umask)
if (( ${rvm_ignore_rvmrc:=0} == 0 ))
then
rvm_rvmrc_files=("/etc/rvmrc" "$HOME/.rvmrc")
if [[ -n "${rvm_prefix:-}" ]] && ! [[ "$HOME/.rvmrc" -ef "${rvm_prefix}/.rvmrc" ]]
then rvm_rvmrc_files+=( "${rvm_prefix}/.rvmrc" )
fi
for rvmrc in "${rvm_rvmrc_files[@]}"
do
if [[ -f "$rvmrc" ]]
then
# pre-gnu
if GREP_OPTIONS="" \command \grep '^\s*rvm .*$' "$rvmrc" >/dev/null 2>&1
then
printf "%b" "
Error:
$rvmrc is for rvm settings only.
rvm CLI may NOT be called from within $rvmrc.
Skipping the loading of $rvmrc"
return 1
else
source "$rvmrc"
fi
fi
done
unset rvm_rvmrc_files
fi
# duplication marker jdgkjnfnkjdngjkfnd4fd
# detect rvm_path if not set
if
[[ -z "${rvm_path:-}" ]]
then
if
[[ -n "${BASH_SOURCE:-$_}" && -f "${BASH_SOURCE:-$_}" ]]
then
rvm_path="${BASH_SOURCE:-$_}"
rvm_path="$( \command \cd "${rvm_path%/scripts/rvm}">/dev/null; pwd )"
rvm_prefix=$( dirname $rvm_path )
elif
[[ "${UID:-}" == "0" || "${USER:-}" == "root" ]]
then
if
(( ${rvm_user_install_flag:-0} == 0 ))
then
rvm_prefix="/usr/local"
rvm_path="${rvm_prefix}/rvm"
else
rvm_prefix="$HOME"
rvm_path="${rvm_prefix}/.rvm"
fi
else
if
[[ -d "$HOME/.rvm" && -s "$HOME/.rvm/scripts/rvm" ]]
then
rvm_prefix="$HOME"
rvm_path="${rvm_prefix}/.rvm"
else
rvm_prefix="/usr/local"
rvm_path="${rvm_prefix}/rvm"
fi
fi
else
# remove trailing slashes, btw. %%/ <- does not work as expected
rvm_path="${rvm_path%%+(\/)}"
fi
# guess rvm_prefix if not set
if [[ -z "${rvm_prefix}" ]]
then
rvm_prefix=$( dirname $rvm_path )
fi
# duplication marker kkdfkgnjfndgjkndfjkgnkfjdgn
[[ -n "${rvm_user_install_flag:-}" ]] ||
case "$rvm_path" in
(/usr/local/rvm) rvm_user_install_flag=0 ;;
($HOME/*|/${USER// /_}*) rvm_user_install_flag=1 ;;
(*) rvm_user_install_flag=0 ;;
esac
export rvm_loaded_flag
if [[ -n "${BASH_VERSION:-}" || -n "${ZSH_VERSION:-}" ]] &&
\typeset -f rvm >/dev/null 2>&1
then
rvm_loaded_flag=1
else
rvm_loaded_flag=0
fi
if
(( ${rvm_loaded_flag:=0} == 0 )) || (( ${rvm_reload_flag:=0} == 1 ))
then
if
[[ -n "${rvm_path}" && -d "$rvm_path" ]]
then
true ${rvm_scripts_path:="$rvm_path/scripts"}
if
[[ ! -f "$rvm_scripts_path/base" ]]
then
printf "%b" "WARNING:
Could not source '$rvm_scripts_path/base' as file does not exist.
RVM will likely not work as expected.\n"
elif
! source "$rvm_scripts_path/base"
then
printf "%b" "WARNING:
Errors sourcing '$rvm_scripts_path/base'.
RVM will likely not work as expected.\n"
else
__rvm_ensure_is_a_function
__rvm_setup
export rvm_version
rvm_version="$(\command \cat "$rvm_path/VERSION") ($(\command \cat "$rvm_path/RELEASE" 2>/dev/null))"
alias rvm-restart="rvm_reload_flag=1 source '${rvm_scripts_path:-${rvm_path}/scripts}/rvm'"
# Try to load RVM ruby if none loaded yet
__path_to_ruby="$( builtin command -v ruby 2>/dev/null || true )"
if
[[ -z "${__path_to_ruby}" ]] ||
[[ "${__path_to_ruby}" != "${rvm_path}"* ]] ||
[[ "${__path_to_ruby}" == "${rvm_path}/bin/ruby" ]]
then
if
[[ -n "${rvm_environments_path:-}" &&
-s "${rvm_environments_path}/default"
]]
then
source "${rvm_environments_path}/default"
elif
[[ "${rvm_environments_path:-}" != "${rvm_path}/environments" &&
-s "${rvm_path}/environments/default"
]]
then
source "${rvm_path}/environments/default"
fi
if
[[ ${rvm_project_rvmrc:-1} -gt 0 ]] &&
! __function_on_stack __rvm_project_rvmrc
then
# Reload the rvmrc, use promptless ensuring shell processes does not
# prompt if .rvmrc trust value is not stored, revert to default on fail
if
rvm_current_rvmrc=""
rvm_project_rvmrc_default=2 rvm_promptless=1 __rvm_project_rvmrc
then
rvm_hook=after_cd
source "${rvm_scripts_path:-${rvm_path}/scripts}/hook"
fi
fi
elif
[[ "${__path_to_ruby}" == "${rvm_path}"* ]] &&
[[ -z "${GEM_HOME:-}" || -z "${GEM_PATH:-}" ]]
then
echo "
Warning: PATH set to RVM ruby but GEM_HOME and/or GEM_PATH not set, see:
https://github.com/wayneeseguin/rvm/issues/3212
" >&2
if
[[ -n "${SUDO_USER:-}" ]]
then
echo "Hint: To fix PATH errors try using 'rvmsudo' instead of 'sudo', see:
" >&2
fi
fi
unset __path_to_ruby
# Makes sure rvm_bin_path is in PATH atleast once.
[[ ":${PATH}:" == *":${rvm_bin_path}:"* ]] || PATH="$PATH:${rvm_bin_path}"
if
(( ${rvm_reload_flag:=0} == 1 ))
then
[[ "${rvm_auto_reload_flag:-0}" == 2 ]] || printf "%b" 'RVM reloaded!\n'
unset __rvm_project_rvmrc_lock
fi
rvm_loaded_flag=1
__rvm_teardown
# Opt-in for custom prompt through by setting:
# rvm_ps1=1
# in either /etc/rvmrc or $HOME/.rvmrc
if
[[ ${rvm_ps1:-0} -eq 1 ]]
then
# Source RVM ps1 functions for a great prompt.
if
[[ -s "$rvm_path/contrib/ps1_functions" ]]
then
source "$rvm_path/contrib/ps1_functions"
elif
[[ -s "/usr/local/rvm/contrib/ps1_functions" ]]
then
source "/usr/local/rvm/contrib/ps1_functions"
fi
if command -v ps1_set >/dev/null 2>&1
then ps1_set
fi
fi
fi
else
printf "%b" "\n$rvm_path ($rvm_path) does not exist."
fi
unset rvm_prefix_needs_trailing_slash rvm_gems_cache_path rvm_gems_path rvm_project_rvmrc_default rvm_gemset_separator rvm_reload_flag
fi
运行 作为 . ~/.rvm/scripts/rvm
的脚本不使用其 shebang 行。它将脚本源到当前 shell。 passthru
的当前 shell 似乎是 /bin/sh
(大多数情况下默认使用 /bin/sh
是合理的)。
如果您希望使用脚本的 shebang,则需要停止 sourcing .
/source
命令。
我已经通过 https://raw.githubusercontent.com/rvm/rvm/master/binscripts/rvm-installer
安装了 RVM我在 Ubuntu 并且我使用 Bash。
安装后,我需要能够基于 installation instructions 获取源 ~/.rvm/scripts/rvm
。
我需要通过 CLI (test.sh) 执行一个脚本来做到这一点,该脚本又调用一个 PHP 脚本 (test.php),该脚本通过 shell 命令进行采购。
一旦我这样做,我就会收到关于 builtin
:
$ ./test.sh
sh: 10: /home/housni/.rvm/scripts/rvm: builtin: not found
这是 test.sh
运行 在 Bash 上调用 test.php
#!/bin/bash
./test.php
这是test.php
#!/usr/bin/php -q
<?php
passthru('. ~/.rvm/scripts/rvm');
?>
当我直接在终端 (bash) 中键入 source ~/.rvm/scripts/rvm
并执行它时,我没有看到任何错误。
在我看来,RVM 脚本试图执行 dash
而不是 bash
,但这并不完全有意义,因为 RVM 脚本以 #!/usr/bin/env bash
开头。
知道我在 PHP 脚本中做错了什么吗?
以下是~/.rvm/scripts/rvm
的内容:
#!/usr/bin/env bash
# rvm : Ruby enVironment Manager
# https://rvm.io
# https://github.com/wayneeseguin/rvm
# partial duplication marker dkjnkjvnckbjncvbkjnvkj
# prevent from loading in sh shells
if
builtin test -n "${BASH_VERSION:-}" -o -n "${ZSH_VERSION:-}" -o -n "${KSH_VERSION:-}"
then
case "`uname`" in
(CYGWIN*) __shell_name="`\command \ps -p $$ | \command \awk 'END {print $NF}'` 2>/dev/null" ;;
(SunOS) __shell_name="`\command \ps -p $$ -o comm=`" ;;
(*) __shell_name="`\command \ps -p $$ -o ucomm=`" ;;
esac
case "$__shell_name" in
(""|dash|sh|ksh|*/dash|*/sh|*/ksh) return 0 ;; # silently stop in sh shells
esac
unset __shell_name
else
return 0
fi
# also duplicated in scripts/base
__rvm_has_opt()
{
if # pre-gnu
[[ -n "${ZSH_VERSION}" ]]
then
setopt | GREP_OPTIONS="" \command \grep "^$" >/dev/null 2>&1 || return $?
elif # mksh
[[ -n "${KSH_VERSION}" ]]
then
set +o | GREP_OPTIONS="" \command \grep "-o $" >/dev/null 2>&1 || return $?
elif # bash
[[ -n "${BASH_VERSION}" ]]
then
[[ ":$SHELLOPTS:" == *"::"* ]] || return $?
else # what is this?!
return 1
fi
}
# Do not allow sourcing RVM in `sh` - it's not supported
# return 0 to exit from sourcing this script without breaking sh
if __rvm_has_opt "posix"
then return 0
fi
# TODO: Alter the variable names to make sense
\export HOME rvm_prefix rvm_user_install_flag rvm_path
HOME="${HOME%%+(\/)}" # Remove trailing slashes if they exist on HOME
[[ -n "${rvm_stored_umask:-}" ]] || export rvm_stored_umask=$(umask)
if (( ${rvm_ignore_rvmrc:=0} == 0 ))
then
rvm_rvmrc_files=("/etc/rvmrc" "$HOME/.rvmrc")
if [[ -n "${rvm_prefix:-}" ]] && ! [[ "$HOME/.rvmrc" -ef "${rvm_prefix}/.rvmrc" ]]
then rvm_rvmrc_files+=( "${rvm_prefix}/.rvmrc" )
fi
for rvmrc in "${rvm_rvmrc_files[@]}"
do
if [[ -f "$rvmrc" ]]
then
# pre-gnu
if GREP_OPTIONS="" \command \grep '^\s*rvm .*$' "$rvmrc" >/dev/null 2>&1
then
printf "%b" "
Error:
$rvmrc is for rvm settings only.
rvm CLI may NOT be called from within $rvmrc.
Skipping the loading of $rvmrc"
return 1
else
source "$rvmrc"
fi
fi
done
unset rvm_rvmrc_files
fi
# duplication marker jdgkjnfnkjdngjkfnd4fd
# detect rvm_path if not set
if
[[ -z "${rvm_path:-}" ]]
then
if
[[ -n "${BASH_SOURCE:-$_}" && -f "${BASH_SOURCE:-$_}" ]]
then
rvm_path="${BASH_SOURCE:-$_}"
rvm_path="$( \command \cd "${rvm_path%/scripts/rvm}">/dev/null; pwd )"
rvm_prefix=$( dirname $rvm_path )
elif
[[ "${UID:-}" == "0" || "${USER:-}" == "root" ]]
then
if
(( ${rvm_user_install_flag:-0} == 0 ))
then
rvm_prefix="/usr/local"
rvm_path="${rvm_prefix}/rvm"
else
rvm_prefix="$HOME"
rvm_path="${rvm_prefix}/.rvm"
fi
else
if
[[ -d "$HOME/.rvm" && -s "$HOME/.rvm/scripts/rvm" ]]
then
rvm_prefix="$HOME"
rvm_path="${rvm_prefix}/.rvm"
else
rvm_prefix="/usr/local"
rvm_path="${rvm_prefix}/rvm"
fi
fi
else
# remove trailing slashes, btw. %%/ <- does not work as expected
rvm_path="${rvm_path%%+(\/)}"
fi
# guess rvm_prefix if not set
if [[ -z "${rvm_prefix}" ]]
then
rvm_prefix=$( dirname $rvm_path )
fi
# duplication marker kkdfkgnjfndgjkndfjkgnkfjdgn
[[ -n "${rvm_user_install_flag:-}" ]] ||
case "$rvm_path" in
(/usr/local/rvm) rvm_user_install_flag=0 ;;
($HOME/*|/${USER// /_}*) rvm_user_install_flag=1 ;;
(*) rvm_user_install_flag=0 ;;
esac
export rvm_loaded_flag
if [[ -n "${BASH_VERSION:-}" || -n "${ZSH_VERSION:-}" ]] &&
\typeset -f rvm >/dev/null 2>&1
then
rvm_loaded_flag=1
else
rvm_loaded_flag=0
fi
if
(( ${rvm_loaded_flag:=0} == 0 )) || (( ${rvm_reload_flag:=0} == 1 ))
then
if
[[ -n "${rvm_path}" && -d "$rvm_path" ]]
then
true ${rvm_scripts_path:="$rvm_path/scripts"}
if
[[ ! -f "$rvm_scripts_path/base" ]]
then
printf "%b" "WARNING:
Could not source '$rvm_scripts_path/base' as file does not exist.
RVM will likely not work as expected.\n"
elif
! source "$rvm_scripts_path/base"
then
printf "%b" "WARNING:
Errors sourcing '$rvm_scripts_path/base'.
RVM will likely not work as expected.\n"
else
__rvm_ensure_is_a_function
__rvm_setup
export rvm_version
rvm_version="$(\command \cat "$rvm_path/VERSION") ($(\command \cat "$rvm_path/RELEASE" 2>/dev/null))"
alias rvm-restart="rvm_reload_flag=1 source '${rvm_scripts_path:-${rvm_path}/scripts}/rvm'"
# Try to load RVM ruby if none loaded yet
__path_to_ruby="$( builtin command -v ruby 2>/dev/null || true )"
if
[[ -z "${__path_to_ruby}" ]] ||
[[ "${__path_to_ruby}" != "${rvm_path}"* ]] ||
[[ "${__path_to_ruby}" == "${rvm_path}/bin/ruby" ]]
then
if
[[ -n "${rvm_environments_path:-}" &&
-s "${rvm_environments_path}/default"
]]
then
source "${rvm_environments_path}/default"
elif
[[ "${rvm_environments_path:-}" != "${rvm_path}/environments" &&
-s "${rvm_path}/environments/default"
]]
then
source "${rvm_path}/environments/default"
fi
if
[[ ${rvm_project_rvmrc:-1} -gt 0 ]] &&
! __function_on_stack __rvm_project_rvmrc
then
# Reload the rvmrc, use promptless ensuring shell processes does not
# prompt if .rvmrc trust value is not stored, revert to default on fail
if
rvm_current_rvmrc=""
rvm_project_rvmrc_default=2 rvm_promptless=1 __rvm_project_rvmrc
then
rvm_hook=after_cd
source "${rvm_scripts_path:-${rvm_path}/scripts}/hook"
fi
fi
elif
[[ "${__path_to_ruby}" == "${rvm_path}"* ]] &&
[[ -z "${GEM_HOME:-}" || -z "${GEM_PATH:-}" ]]
then
echo "
Warning: PATH set to RVM ruby but GEM_HOME and/or GEM_PATH not set, see:
https://github.com/wayneeseguin/rvm/issues/3212
" >&2
if
[[ -n "${SUDO_USER:-}" ]]
then
echo "Hint: To fix PATH errors try using 'rvmsudo' instead of 'sudo', see:
" >&2
fi
fi
unset __path_to_ruby
# Makes sure rvm_bin_path is in PATH atleast once.
[[ ":${PATH}:" == *":${rvm_bin_path}:"* ]] || PATH="$PATH:${rvm_bin_path}"
if
(( ${rvm_reload_flag:=0} == 1 ))
then
[[ "${rvm_auto_reload_flag:-0}" == 2 ]] || printf "%b" 'RVM reloaded!\n'
unset __rvm_project_rvmrc_lock
fi
rvm_loaded_flag=1
__rvm_teardown
# Opt-in for custom prompt through by setting:
# rvm_ps1=1
# in either /etc/rvmrc or $HOME/.rvmrc
if
[[ ${rvm_ps1:-0} -eq 1 ]]
then
# Source RVM ps1 functions for a great prompt.
if
[[ -s "$rvm_path/contrib/ps1_functions" ]]
then
source "$rvm_path/contrib/ps1_functions"
elif
[[ -s "/usr/local/rvm/contrib/ps1_functions" ]]
then
source "/usr/local/rvm/contrib/ps1_functions"
fi
if command -v ps1_set >/dev/null 2>&1
then ps1_set
fi
fi
fi
else
printf "%b" "\n$rvm_path ($rvm_path) does not exist."
fi
unset rvm_prefix_needs_trailing_slash rvm_gems_cache_path rvm_gems_path rvm_project_rvmrc_default rvm_gemset_separator rvm_reload_flag
fi
运行 作为 . ~/.rvm/scripts/rvm
的脚本不使用其 shebang 行。它将脚本源到当前 shell。 passthru
的当前 shell 似乎是 /bin/sh
(大多数情况下默认使用 /bin/sh
是合理的)。
如果您希望使用脚本的 shebang,则需要停止 sourcing .
/source
命令。