我有一个功能~/.zshrc:
findPort() {
lsof -t -i :$1
}
Run Code Online (Sandbox Code Playgroud)
通常的调用是findPort 3306.
我想以提升的权限运行它。但我得到“找不到命令”。
? git sudo findPort 3306
sudo: findPort: command not found
Run Code Online (Sandbox Code Playgroud)
我认为原因是 root 用户要么作为非交互式 shell 运行(因此不指代 .zshrc),要么指代不同的 .zshrc.
我见过关于 的类似问题alias,但没有关于用户定义函数的问题。此问题的答案alias涉及将别名添加到~/.zshrc:
alias sudo='nocorrect sudo '
Run Code Online (Sandbox Code Playgroud)
也许:
alias sudo='sudo '
Run Code Online (Sandbox Code Playgroud)
我已经尝试了这两种解决方案,但问题仍然存在(是的,我已经重新启动了 shell)。
我还尝试运行sudo chsh以确保我的 root shell 在zsh. 这些解决方案都没有消除“找不到命令”的问题。
有没有办法在 sudo 下运行我的用户定义函数?
Sté*_*las 14
sudo直接运行命令,而不是通过 shell,即使它运行了一个 shell 来运行该命令,它也将是一个新的 shell 调用,而不是读取你的~/.zshrc(即使它启动了一个交互式 shell,它可能会读取root's ~/.zshrc,除非您已配置sudo为不重置$HOME变量,否则不是您的)。
在这里,您需要告诉sudo启动一个新的zshshell,并告诉它在运行该函数之前zsh读取您的信息~/.zshrc:
sudo zsh -c '. $0; "$@"' ~/.zshrc findPort 3306
Run Code Online (Sandbox Code Playgroud)
或者:
sudo zsh -c '. $0; findPort 3306' ~/.zshrc
Run Code Online (Sandbox Code Playgroud)
或者与zsh调用的 new 共享您当前的 zsh 函数sudo:
sudo zsh -c "$(functions); findPort 3306"
Run Code Online (Sandbox Code Playgroud)
尽管如果您定义了很多函数(例如使用完成系统时),您可能会收到arg list too long错误。因此,您可能希望将其限制为findPort函数(以及它所依赖的所有其他函数(如果有)):
sudo zsh -c "$(functions findPort); findPort 3306"
Run Code Online (Sandbox Code Playgroud)
你也可以这样做:
sudo zsh -c "(){$functions[findPort]} 3306"
Run Code Online (Sandbox Code Playgroud)
将findPort函数的代码嵌入到传递 3306 参数的匿名函数中。甚至:
sudo zsh -c "$functions[findPort]" findPort 3306
Run Code Online (Sandbox Code Playgroud)
(传递给的内联脚本-c 是函数的主体)。
您可以使用辅助函数,例如:
zsudo() sudo zsh -c "$functions[$1]" "$@"
Run Code Online (Sandbox Code Playgroud)
不使用:
sdo() { sudo zsh -c "(){$functions[$1]} ${@:2}" }
由于 的参数sdo将经历另一个级别的外壳解析。相比:
$ e() echo "$@"
$ sdo e 'tname;uname'
tname
Linux
$ zsudo e 'tname;uname'
tname;uname
Run Code Online (Sandbox Code Playgroud)