在 Cygwin 的 Root 用户/sudo 等价物?

我想在 Cygwin 运行 bash 脚本。

我得到 Must run as root, i.e. sudo ./scriptname错误。

chmod 777 scriptname没有任何帮助。

我一直在寻找在 Cygwin 上模仿 sudo、添加 root 用户的方法,因为调用“ su”会显示错误 su: user root does not exist,任何有用的东西都没有找到。

有人有什么建议吗?

185647 次浏览

您可能需要以管理员的身份运行 cygwin shell。您可以右键单击快捷方式并单击“以管理员身份运行”,或进入快捷方式的属性并在兼容性部分中检查它。小心点。Root 权限可能是危险的。

我发现了 Sudo 换 Cygwin,也许可以,它是一个客户机/服务器应用程序,使用一个 python 脚本在 windows (pty)中生成一个子进程,并将用户的 tty 和进程 I/O 连接起来。

它需要 windows 中的 Python 和 Python 模块 greenlet,以及 Cygwin 中的 eventlet。

试试:

chmod -R ug+rwx <dir>

其中 <dir>是您所在的目录 要更改权限。

我自己无法完全测试它,也没有合适的脚本可以试用,而且我也不是 Linux 专家,但是你可以黑进一些类似的东西。

我已经尝试了这些步骤,它们“似乎”工作,但不知道它们是否足以满足您的需要。

为了避免“ root”用户的缺失:

  • 在 LOCAL windows 机器上创建一个名为“ root”的用户,使其成为“ Administrator”组的成员
  • 为所有用户将 bin/bash.exe 标记为“ Run as Administrator”(显然,您必须在需要时打开/关闭它)
  • 右键点击 Cygwin.bat 文件,按住左边的 shift 文件资源管理器按钮
  • 选择“作为不同用户运行”
  • 输入.root 作为用户名,然后输入密码。

然后,在 cygwin 中将您作为名为“ root”的用户运行,加上 bash.exe 文件中的“ Run as Administrator”可能就足够了。

不过你还是需要一个 sudo。

我在/bin 中创建了一个名为“ sudo”的文件,并使用这个命令行将命令发送到 su,从而伪造了这个命令(其他更了解 Linux 的人可能伪造得更好) :

su -c "$*"

命令行“ sudo vim”和其他命令对我来说似乎没有问题,所以您可能想尝试一下。

有兴趣知道这是否适合你的需要。

我是通过谷歌来到这里的,我相信我已经找到了在 Cygwin 中获得一个功能完善的 root 提示的方法。

这是我的步骤。

首先,您需要将 Windows 管理员帐户重命名为“ root” 通过打开 start manu 并键入“ gpedit.msc”来完成此操作

编辑 本地电脑政策 > 计算机配置 > 视窗设定 > 保安设定 > 本地政策 > 保安选项 > 帐户: 重命名管理员帐户

然后,如果还没有启用该帐户,则必须启用该帐户。 本地电脑政策 > 计算机配置 > 视窗设定 > 保安设定 > 本地政策 > 保安选项 > 帐户: 管理员帐户状态

现在注销并登录到 root 帐户。

现在为 cygwin 设定一个环境变量: 右击我的电脑 > 属性

点击(在左侧边栏)“高级系统设置”

在底部点击“环境变量”按钮

在“系统变量”下单击“新建...”按钮

对于这个名字,把“ cygwin”没有引号。 对于该值,输入您的 cygwin 根目录(我的目录是 C: cygwin)

按确定并关闭所有这些返回到桌面。

打开 Cygwin 终端(Cygwin.bat)

编辑文件/etc/passwd 然后换台

管理员 : 未使用: 500:503: U-机器管理员,S-1-5-21-123456778-1234567890-1234567890-500:/home/Administrator:/bin/bash

为此(您的数字和机器名称将不同,只需确保将突出显示的数字更改为0!)

Root : 未使用: 0:0: U-机器根,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 用户帐户。

在所有这些之后,通过在 Explorer 中双击新的“ su.bat”手动运行它。输入密码,然后关闭窗口。

现在尝试从 cygwin 运行 su 命令,看看是否一切正常。

我通常做的是有一个注册表“ Open Here”助手,以便从我的计算机中的任何地方轻松地打开具有管理特权的 cygwin shell。

注意你必须安装 cygwin“ chere”软件包,首先从一个提升的 cygwin shell 使用“ chere -i -m”。

假设您的 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 文件中以运行它... ... 或者您可以手动添加这些值。

这个答案是基于 另一个答案的。首先,确保您的帐户在管理员组中。

接下来,创建一个通用的“ 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 提示符,并且这个过程已经通用化,因此您可以使用任何类型的命令。

使用此命令可以从任何目录上下文菜单中获得一个运行 bash 或 cmd 的管理窗口。只需右键单击一个目录名,然后选择条目或点击突出显示的按钮。

这是基于 chere 工具和来自 link _ boy 的(对我来说)不幸不起作用的答案。我用 Windows8的时候它工作得很好,

副作用是管理 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\""

我在 超级用户上回答了这个问题,但是只是在 OP 无视了当时这个问题的唯一答案——毫无帮助的答案之后。

以下是在 Cygwin 提升权限的正确方法,摘自我在“超级用户”上的回答:

我在 Cygwin 的邮件列表上找到了答案。要在 Cygwin 以更高的权限运行 command,在命令前面加上如下的 cygstart --action=runas:

$ cygstart --action=runas command

这将打开一个 Windows 对话框,要求输入管理员密码,如果输入了正确的密码,则运行该命令。

这很容易编写脚本,只要 ~/bin在路径中:

#!/usr/bin/bash
cygstart --action=runas "$@"

现在让文件可执行:

$ chmod +x ~/bin/sudo

现在可以用 真正的高级特权运行命令了:

$ sudo elevatedCommand

您可能需要将 ~/bin添加到路径中。您可以在 Cygwin CLI 上运行以下命令,或者将其添加到 ~/.bashrc:

$ PATH=$HOME/bin:$PATH

在64位 Windows8上测试。

您也可以将这个命令的别名添加到 ~/.bashrc,而不是上面的步骤:

# alias to simulate sudo
alias sudo='cygstart --action=runas'

这根线的 GitHub 为 CygWin 提供了一个增强 SUDO 的新提案,命名为 TOUACEXT:

  • 自动打开 sudoserver.py。
  • 在超时后自动关闭 sudoserver.py (默认为15分钟)。
  • 为管理员用户请求 UAC 提升提示是/否样式。
  • 为非管理员用户请求管理员用户/密码。
  • 与管理帐户进行远程操作(SSH)。
  • 创建日志。

还在 测试前频道,不过看起来有用。

或者安装 syswin 包,其中包含一个用于 cygwin 的 su 端口: http://sourceforge.net/p/manufacture/wiki/syswin-su/

基于 Dotancohen 的回答我使用了一个化名:

alias sudo="cygstart --action=runas"

作为一种魅力:

sudo chown User:Group <file>

如果您已经安装了 SysInternals,那么您甚至可以以系统用户的身份轻松启动命令 shell

sudo psexec -i -s -d cmd

使用 cygwin shell 和相应的 subshell 以管理员特权进行操作的一个非常简单的方法是更改打开初始 shell 的 链接的属性。

以下内容适用于 Windows7 + (可能也适用于以前的版本,但我还没有检查)

我通常从 开始按钮(或桌面)的 cygwin-link 启动 cygwin shell。 然后,我更改了选项卡中 cygwin-link 的属性

/兼容性/特权级别/

然后勾选框,

“以管理员身份运行此程序”

这允许 cygwin shell 以管理员特权和相应的 subshell 打开。

似乎 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

由于对可用的解决方案不满意,我采用了 Nu774的脚本来增加安全性,并使其更容易设置和使用。该项目是可用的 在 Github 上

要使用它,只需下载 cygwin-sudo.py并通过 python3 cygwin-sudo.py **yourcommand**运行它。

为了方便起见,你可以设置一个别名:

alias sudo="python3 /path-to-cygwin-sudo/cygwin-sudo.py"

我参加了这次讨论,希望了解不同操作系统中 sudo实现的一些细节。通过阅读,我发现@brian-white (https://stackoverflow.com/a/42956057/3627676)的解决方案是有用的,但是可以稍微改进一下。我避免创建临时文件,而是通过单个脚本执行所有内容。

此外,我还研究了在单个窗口/控制台中输出的改进的下一步。不幸的是,没有任何成功。我尝试使用命名管道捕获 STDOUT/STDERR 并在主窗口中打印。但是子进程没有写入命名管道。但是,写入常规文件效果很好。

我放弃了任何寻找根本原因的尝试,并保持当前的解决方案不变。希望我的帖子也能派上用场。

改善措施:

  • 没有临时文件
  • 不解析和重新构造命令行选项
  • 等待上级命令
  • 使用 minttybash,如果第一个没有找到
  • 返回命令退出代码


#!/bin/bash


# Being Administrators, invoke the command directly
id -G | grep -qw 544 && {
"$@"
exit $?
}


# The CYG_SUDO variable is used to control the command invocation
[ -z "$CYG_SUDO" ] && {
mintty="$( which mintty 2>/dev/null )"
export CYG_SUDO="$$"
cygstart --wait --action=runas $mintty /bin/bash "$0" "$@"
exit $?
}


# Now we are able to:
# -- launch the command
# -- display the message
# -- return the exit code
"$@"
RETVAL=$?


echo "$0: Press  to close window..."
read


exit $RETVAL


基于@mat-khor 的回答,我使用 syswin su.exe,将其保存为 manufacture-syswin-su.exe,并编写了这个包装器脚本。它处理命令的 stdout 和 stderr 的重定向,因此可以在管道中使用,等等。此外,脚本退出时带有给定命令的状态。

限制:

  • Syswin-su 选项当前被硬编码为使用当前用户。将 env USERNAME=...前置到脚本调用会覆盖它。如果需要其他选项,脚本必须区分 syswin-su 和命令参数,例如在第一个 --处进行分割。
  • 如果 UAC 提示被取消或拒绝,脚本将挂起。

.

#!/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