我正在尝试在 Cygwin 中运行 bash 脚本。
我得到Must run as root, i.e. sudo ./scriptname
错误。
chmod 777 scriptname
无济于事。
我一直在寻找在 Cygwin 上模仿 sudo 的方法,以添加 root 用户,因为调用“su”会呈现错误su: user root does not exist
,任何有用的东西,但什么也没找到。
有人有什么建议吗?
我在SuperUser上回答了这个问题,但只是在 OP 忽略了当时唯一回答这个问题的无用答案之后。
这是在 Cygwin 中提升权限的正确方法,复制自我自己对 SuperUser 的回答:
我在 Cygwin 邮件列表上找到了答案。要command
在 Cygwin 中以提升的权限运行,请在命令之前添加cygstart --action=runas
如下内容:
$ cygstart --action=runas command
这将打开一个 Windows 对话框,询问管理员密码并在输入正确密码时运行命令。
只要~/bin
在您的路径中,这很容易编写脚本。创建一个~/bin/sudo
包含以下内容的文件:
#!/usr/bin/bash
cygstart --action=runas "$@"
现在使文件可执行:
$ chmod +x ~/bin/sudo
现在您可以使用真正提升的权限运行命令:
$ sudo elevatedCommand
您可能需要添加~/bin
到您的路径。您可以在 Cygwin CLI 上运行以下命令,或将其添加到~/.bashrc
:
$ PATH=$HOME/bin:$PATH
在 64 位 Windows 8 上测试。
您也可以代替上述步骤为此命令添加别名~/.bashrc
:
# alias to simulate sudo
alias sudo='cygstart --action=runas'
您可能需要以管理员身份运行 cygwin shell。您可以右键单击快捷方式并单击以管理员身份运行,或者进入快捷方式的属性并在兼容性部分进行检查。请注意.... root 权限可能很危险。
基于dotancohen 的回答,我使用了别名:
alias sudo="cygstart --action=runas"
用作魅力:
sudo chown User:Group <file>
如果您安装了 SysInternals,您甚至可以非常轻松地以系统用户身份启动命令 shell
sudo psexec -i -s -d cmd
我找到了 sudo-for-cygwin,也许这会起作用,它是一个客户端/服务器应用程序,它使用 python 脚本在 windows (pty) 中生成一个子进程并桥接用户的 tty 和进程 I/O。
它需要 windows 中的 python 和 Python 模块 greenlet,以及 Cygwin 中的 eventlet。
似乎cygstart/runas
没有正确处理"$@"
,因此具有包含空格的参数(可能还有其他 shell 元字符——我没有检查)的命令将无法正常工作。
我决定只编写一个小sudo
脚本,通过编写一个正确执行参数的临时脚本来工作。
#! /bin/bash
# If already admin, just run the command in-line.
# This works on my Win10 machine; dunno about others.
if id -G | grep -q ' 544 '; then
"$@"
exit $?
fi
# cygstart/runas doesn't handle arguments with spaces correctly so create
# a script that will do so properly.
tmpfile=$(mktemp /tmp/sudo.XXXXXX)
echo "#! /bin/bash" >>$tmpfile
echo "export PATH=\"$PATH\"" >>$tmpfile
echo "$1 \\" >>$tmpfile
shift
for arg in "$@"; do
qarg=`echo "$arg" | sed -e "s/'/'\\\\\''/g"`
echo " '$qarg' \\" >>$tmpfile
done
echo >>$tmpfile
# cygstart opens a new window which vanishes as soon as the command is complete.
# Give the user a chance to see the output.
echo "echo -ne '\n$0: press <enter> to close window... '" >>$tmpfile
echo "read enter" >>$tmpfile
# Clean up after ourselves.
echo "rm -f $tmpfile" >>$tmpfile
# Do it as Administrator.
cygstart --action=runas /bin/bash $tmpfile
或者安装 syswin 包,其中包含 cygwin 的 su 端口:http: //sourceforge.net/p/manufacture/wiki/syswin-su/
这个答案基于另一个答案。首先,确保您的帐户在管理员组中。
接下来,创建一个具有以下内容的通用“runas-admin.bat”文件:
@if (1==1) @if(1==0) @ELSE
@echo off&SETLOCAL ENABLEEXTENSIONS
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"||(
cscript //E:JScript //nologo "%~f0" %*
@goto :EOF
)
FOR %%A IN (%*) DO (
"%%A"
)
@goto :EOF
@end @ELSE
args = WScript.Arguments;
newargs = "";
for (var i = 0; i < args.length; i++) {
newargs += "\"" + args(i) + "\" ";
}
ShA=new ActiveXObject("Shell.Application");
ShA.ShellExecute("cmd.exe","/c \""+WScript.ScriptFullName+" "+newargs+"\"","","runas",5);
@end
然后像这样执行批处理文件:
./runas-admin.bat "<command1> [parm1, parm2, ...]" "<command2> [parm1, parm2, ...]"
例如:
./runas-admin.bat "net localgroup newgroup1 /add" "net localgroup newgroup2 /add"
只需确保将每个单独的命令用双引号括起来。使用此方法您只会获得一次 UAC 提示,并且此过程已被通用化,因此您可以使用任何类型的命令。
在此线程中,来自 GitHub 的用于增强 CygWin 的 SUDO 的新提议,名为TOUACext:
仍处于Pre-Beta 阶段,但似乎正在工作。
我通过谷歌登陆这里,我实际上相信我已经找到了一种在 cygwin 中获得功能齐全的 root 提示的方法。
这是我的步骤。
首先,您需要将 Windows 管理员帐户重命名为“root”,方法是打开开始菜单并键入“gpedit.msc”
编辑本地计算机策略 > 计算机配置 > Windows 设置 > 安全设置 > 本地策略 > 安全选项 > 帐户下的条目:重命名管理员帐户
然后,如果尚未启用该帐户,则必须启用该帐户。本地计算机策略 > 计算机配置 > Windows 设置 > 安全设置 > 本地策略 > 安全选项 > 帐户:管理员帐户状态
现在注销并登录到 root 帐户。
现在为 cygwin 设置一个环境变量。要做到这一点的简单方法:右键单击我的电脑 > 属性
单击(在左侧边栏上)“高级系统设置”
在底部附近单击“环境变量”按钮
在“系统变量”下单击“新建...”按钮
对于名称,请输入不带引号的“cygwin”。对于该值,请输入您的 cygwin 根目录。(我的是 C:\cygwin )
按确定并关闭所有这些以返回桌面。
打开 Cygwin 终端 (cygwin.bat)
编辑文件 /etc/passwd 并更改行
管理员:未使用:500:503:U - MACHINE\Administrator,S-1-5-21-12345678-1234567890-1234567890-500 :/home/Administrator:/bin/bash
为此(您的数字和机器名称会有所不同,只需确保将突出显示的数字更改为 0!)
根:未使用: 0:0 :U- MACHINE\root ,S-1-5-21-12345678-1234567890-1234567890- 0:/root :/bin/bash
现在一切都完成了,接下来的一点将使“su”命令起作用。(不完美,但它的功能足以使用。我认为脚本无法正常运行,但是嘿,你已经到了这一步,也许你能找到方法。请分享)
在 cygwin 中运行此命令以完成交易。
mv /bin/su.exe /bin/_su.exe_backup
cat > /bin/su.bat << "EOF"
@ECHO OFF
RUNAS /savecred /user:root %cygwin%\cygwin.bat
EOF
ln -s /bin/su.bat /bin/su
echo ''
echo 'All finished'
退出 root 帐户并重新进入您的普通 Windows 用户帐户。
毕竟,通过在资源管理器中双击它来手动运行新的“su.bat”。输入您的密码,然后关闭窗口。
现在尝试从 cygwin 运行 su 命令,看看是否一切正常。
由于对可用的解决方案不满意,我采用了nu774 的脚本来增加安全性并使其更易于设置和使用。该项目在 Github上可用
要使用它,只需下载cygwin-sudo.py
并通过python3 cygwin-sudo.py **yourcommand**
.
为方便起见,您可以设置别名:
alias sudo="python3 /path-to-cygwin-sudo/cygwin-sudo.py"
使用它从任何目录上下文菜单中获取运行 bash 或 cmd 的管理窗口。只需右键单击目录名称,然后选择条目或点击突出显示的按钮。
这是基于 chere 工具和来自 link_boy 的不幸的是不工作的答案(对我来说)。使用 Windows 8 对我来说效果很好,
副作用是管理 cmd 窗口中的颜色不同。要在 bash 上使用它,您可以更改管理员用户的 .bashrc 文件。
我无法运行“背景”版本(右键单击打开的目录)。随意添加它。
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Directory\shell\cygwin_bash]
@="&Bash Prompt Here"
"Icon"="C:\\cygwin\\Cygwin.ico"
[HKEY_CLASSES_ROOT\Directory\shell\cygwin_bash\command]
@="C:\\cygwin\\bin\\bash -c \"/bin/xhere /bin/bash.exe '%L'\""
[HKEY_CLASSES_ROOT\Directory\shell\cygwin_bash_root]
@="&Root Bash Prompt Here"
"Icon"="C:\\cygwin\\Cygwin.ico"
"HasLUAShield"=""
[HKEY_CLASSES_ROOT\Directory\shell\cygwin_bash_root\command]
@="runas /savecred /user:administrator \"C:\\cygwin\\bin\\bash -c \\\"/bin/xhere /bin/bash.exe '%L'\\\"\""
[HKEY_CLASSES_ROOT\Directory\shell\cygwin_cmd]
@="&Command Prompt Here"
[HKEY_CLASSES_ROOT\Directory\shell\cygwin_cmd\command]
@="cmd.exe /k cd %L"
"HasLUAShield"=""
[HKEY_CLASSES_ROOT\Directory\shell\cygwin_cmd_root]
@="Roo&t Command Prompt Here"
"HasLUAShield"=""
[HKEY_CLASSES_ROOT\Directory\shell\cygwin_cmd_root\command]
@="runas /savecred /user:administrator \"cmd.exe /t:1E /k cd %L\""
让 cygwin shell 和相应的子 shell 以管理员权限运行的一种非常简单的方法是更改打开初始 shell的链接的属性。
以下对 Windows 7+ 有效(可能也适用于以前的版本,但我没有检查过)
我通常从开始按钮(或桌面)中的 cygwin-link 启动 cygwin shell 。然后,我在选项卡中更改了 cygwin-link 的属性
/兼容性/权限级别/
并勾选了复选框,
“以管理员身份运行此程序”
这允许 cygwin shell 以管理员权限和相应的子 shell 打开。
我遇到了这个讨论,以寻找有关sudo
在不同操作系统中实现的一些细节。阅读它我发现@brian-white ( https://stackoverflow.com/a/42956057/3627676 ) 的解决方案很有用,但可以稍微改进。我避免创建临时文件并实施以通过单个脚本执行所有内容。
我还研究了在单个窗口/控制台中改进输出的下一步。不幸的是,没有任何成功。我尝试使用命名管道来捕获 STDOUT/STDERR 并在主窗口中打印。但是子进程没有写入命名管道。但是写入常规文件效果很好。
我放弃了任何寻找根本原因的尝试,并保留了当前的解决方案。希望我的帖子也能有用。
改进:
mintty
or bash
,如果没有找到第一个#!/bin/bash # 作为管理员,直接调用命令 标识-G | grep -qw 544 && { “$@” 退出 $? } # CYG_SUDO 变量用于控制命令调用 [ -z "$CYG_SUDO" ] && { mintty="$( 哪个 mintty 2>/dev/null )" 出口 CYG_SUDO="$$" cygstart --wait --action=runas $mintty /bin/bash "$0" "$@" 退出 $? } # 现在我们可以: # -- 启动命令 # -- 显示消息 # -- 返回退出代码 “$@” RETVAL=$? echo "$0: 按关闭窗口..." 读 退出 $RETVAL
根据@mat-khor 的回答,我将 syswinsu.exe
保存为manufacture-syswin-su.exe
,然后编写了这个包装脚本。它处理命令的 stdout 和 stderr 的重定向,因此它可以在管道等中使用。此外,脚本以给定命令的状态退出。
限制:
env USERNAME=...
到脚本调用会覆盖它。如果需要其他选项,脚本必须区分 syswin-su 和命令参数,例如在第一个--
..
#!/bin/bash
set -e
# join command $@ into a single string with quoting (required for syswin-su)
cmd=$( ( set -x; set -- "$@"; ) 2>&1 | perl -nle 'print $1 if /\bset -- (.*)/' )
tmpDir=$(mktemp -t -d -- "$(basename "$0")_$(date '+%Y%m%dT%H%M%S')_XXX")
mkfifo -- "$tmpDir/out"
mkfifo -- "$tmpDir/err"
cat >> "$tmpDir/script" <<-SCRIPT
#!/bin/env bash
$cmd > '$tmpDir/out' 2> '$tmpDir/err'
echo \$? > '$tmpDir/status'
SCRIPT
chmod 700 -- "$tmpDir/script"
manufacture-syswin-su -s bash -u "$USERNAME" -m -c "cygstart --showminimized bash -c '$tmpDir/script'" > /dev/null &
cat -- "$tmpDir/err" >&2 &
cat -- "$tmpDir/out"
wait $!
exit $(<"$tmpDir/status")
只需简化接受的答案,在 Cygwin 终端中复制以下内容即可:
cat <<EOF >> /bin/sudo
#!/usr/bin/bash
cygstart --action=runas "\$@"
EOF
chmod +X /bin/sudo
我自己无法对此进行完全测试,我没有合适的脚本来尝试它,而且我不是 Linux 专家,但你可能能够破解足够接近的东西。
我已经尝试了这些步骤,它们“似乎”工作,但不知道它是否足以满足您的需求。
为了解决缺少“root”用户的问题:
然后,这将在 cygwin 中以名为“root”的用户身份运行您,再加上 bash.exe 文件上的“以管理员身份运行”可能就足够了。
但是你仍然需要一个 sudo。
我通过在 /bin 中创建一个名为 'sudo' 的文件并使用此命令行将命令发送到 su 来伪造它(而其他具有更多 linux 知识的人可能会更好地伪造它):
su -c "$*"
命令行 'sudo vim' 和其他对我来说似乎工作正常,所以你可能想尝试一下。
有兴趣知道这是否适合您的需求。
我通常做的是有一个注册表“在此处打开”帮助程序,以便从我计算机的任何位置轻松打开具有管理权限的 cygwin shell。
请注意,您必须安装 cygwin “chere” 软件包,chere -i -m
首先使用提升的 cygwin shell 中的“”。
假设您的 cygwin 安装在C:\cygwin...
这是注册表代码:
Windows Registry Editor Version 5.00
[-HKEY_CLASSES_ROOT\Directory\shell\cygwin_bash]
[HKEY_CLASSES_ROOT\Directory\shell\cygwin_bash]
@="Open Cygwin Here as Root"
"HasLUAShield"=""
[HKEY_CLASSES_ROOT\Directory\shell\cygwin_bash\command]
@="c:\\cygwin\\bin\\mintty.exe -i /Cygwin-Terminal.ico -e /bin/xhere /bin/bash.exe"
[-HKEY_CLASSES_ROOT\Directory\Background\shell\cygwin_bash]
[HKEY_CLASSES_ROOT\Directory\Background\shell\cygwin_bash]
@="Open Cygwin Here as Root"
"HasLUAShield"=""
[HKEY_CLASSES_ROOT\Directory\Background\shell\cygwin_bash\command]
@="c:\\cygwin\\bin\\mintty.exe -i /Cygwin-Terminal.ico -e /bin/xhere /bin/bash.exe"
[-HKEY_CLASSES_ROOT\Drive\shell\cygwin_bash]
[HKEY_CLASSES_ROOT\Drive\shell\cygwin_bash]
@="Open Cygwin Here as Root"
"HasLUAShield"=""
[HKEY_CLASSES_ROOT\Drive\shell\cygwin_bash\command]
@="c:\\cygwin\\bin\\mintty.exe -i /Cygwin-Terminal.ico -e /bin/xhere /bin/bash.exe"
希望这可以帮助。请让我知道这对你有没有用。谢谢。
PS:您可以获取此代码,复制并粘贴它并将其保存在 name.reg 文件中以运行它...或者您可以手动添加值。
尝试:
chmod -R ug+rwx <dir>
<dir>
您要更改权限的目录在哪里。