เนื่องจากไม่มีคำสั่งsudoในCygwinสคริปต์ที่ฉันต้องการเรียกใช้ล้มเหลวด้วย
./install.sh: line N: sudo: command not found
วิธีมาตรฐานในการแก้ไขปัญหานี้คืออะไร? การแก้ไขสคริปต์เพื่อลบsudo
? กำลังรับsudo
เครื่องมือที่คล้ายสำหรับ Windows?
เนื่องจากไม่มีคำสั่งsudoในCygwinสคริปต์ที่ฉันต้องการเรียกใช้ล้มเหลวด้วย
./install.sh: line N: sudo: command not found
วิธีมาตรฐานในการแก้ไขปัญหานี้คืออะไร? การแก้ไขสคริปต์เพื่อลบsudo
? กำลังรับsudo
เครื่องมือที่คล้ายสำหรับ Windows?
คำตอบ:
ฉันเขียนTOUACExt (ค่อนข้างง่าย) สำหรับSUDO สำหรับ CygWinซึ่งเป็นสคริปต์อัตโนมัติเชลล์รุ่นเบต้าที่เข้าใกล้พฤติกรรมของ Classical sudo
สำหรับ Linux:
การติดตั้งจำเป็นต้องคัดลอกสี่.sh
สคริปต์ไปยังไดเรกทอรีพา ธ บางส่วนสร้างนามแฝงและเพียงไม่กี่ขั้นตอนรายละเอียดเพิ่มเติมในเธรด
ผลลัพธ์ : คุณพิมพ์เพียงครั้งเดียวsudo YourCommand
และรับผลลัพธ์โดยไม่ต้องกังวลเกี่ยวกับกระบวนการที่เหลือ
วิธีหนึ่งคือการสร้างคำสั่ง "sudo" ปลอมด้วยเนื้อหาต่อไปนี้:
#!/usr/bin/bash
"$@"
สิ่งนี้จะทำให้การinstall.sh
ดำเนินการต่อเนื่องจากพบ sudo
สิ่งนี้ไม่ยกระดับสิทธิ์ใช้งานเหมือนที่ sudo จริงทำ หากคุณต้องการสิทธิ์ยกระดับเริ่มต้นเชลล์ cygwin ด้วยจากบัญชีที่มีสิทธิ์ระดับผู้ดูแลระบบ (XP) หรือคลิก r บน cygwin.bat และ"run as administrator" (Vista, Win7)
bash
: ทำไมงานนี้? manpage ไม่ได้พูดอะไรเกี่ยวกับ$@
การทำอะไรที่sudo
เหมือน มันเป็นเพียงข้อโต้แย้งทั้งหมดของสคริปต์ และคำพูดรอบ ๆ มันจะไม่ฟุ่มเฟือยในกรณีนี้หรือไม่? มิฉะนั้นถ้าคุณทำsudo foo bar
แล้วมันจะพยายามดำเนินการ"foo bar"
เป็นคำสั่งเดียวซึ่งอาจไม่มีอยู่เนื่องจากความกลัวที่ไม่ลงตัวของช่องว่างบนระบบที่คล้ายกับ UNIX
"$@"
(เมื่ออ้างสองครั้ง) ทำงานแตกต่างจาก"$*"
: มันขยายเป็นคำที่แยกต่างหากสำหรับตัวแปรตำแหน่งทุก ตัวอย่าง:ถ้า$1 == "foo bar"
และ$2 == "baz"
จากนั้น"$@"
คือ"foo bar" baz
- หนึ่งคำสำหรับแต่ละพารามิเตอร์ (ไม่เหมือน"$*"
กันซึ่งส่งผล"foo bar baz"
ให้เป็นหนึ่งคำ) ดูคู่มือการใช้งานbash
ส่วนพารามิเตอร์ , หมวดพารามิเตอร์พิเศษ ผลลัพธ์สุดท้ายของสคริปต์ของ Peon คือมันประมวลผลการขัดแย้งของมันอย่างที่ผ่านมา
sudo
ส่วนไหนจะเข้ามา ตัวอย่างด้านบนไม่ได้ทำอะไรจากระยะไกลในทิศทางนั้นใช่ไหม
sudo
จะยกระดับสิทธิพิเศษจากมนุษย์ให้ถึงroot
ก่อนที่จะใช้คำสั่ง ใน Cygwin ไม่มีสิ่งนั้นดังนั้นสคริปต์ปลอมของ Peon (ซึ่งคุณควรจะตั้งชื่อsudo
) เพียงแค่เรียกใช้คำสั่งโดยตรงโดยไม่เปลี่ยนสิทธิ์ของมัน (ซึ่งหมายความว่าคุณอาจต้องเรียกใช้./install.sh
ในฐานะผู้ดูแลระบบ)
runas
ควรใช้งานไม่ต้องพึ่งพา UAC และแจ้งรหัสผ่านด้วยตัวเอง ฉันเพิ่งสับสนว่าทำไมสคริปต์ในคำตอบดูเหมือนไม่ได้ทำในสิ่งที่ชื่อโดยนัยซึ่งฉันถือว่าเป็นเป้าหมาย ขออภัยในความโง่เขลาของฉัน ;-)
ผมพบคำตอบในรายชื่อที่ส่งของ cygwin ในการรันcommand
ด้วยสิทธิ์ยกระดับใน Cygwin ให้ทำหน้าคำสั่งด้วยcygstart --action=runas
วิธีนี้:
$ cygstart --action=runas command
นี่จะเป็นการเปิดกล่องโต้ตอบ Windows เพื่อขอรหัสผ่านผู้ดูแลระบบและเรียกใช้คำสั่งหากป้อนรหัสผ่านที่เหมาะสม
นี่เป็นสคริปต์อย่างง่ายดายตราบใดที่~/bin
อยู่ในเส้นทางของคุณ:
$ cat ~/bin/sudo
#!/usr/bin/bash
cygstart --action=runas "$@"
$ PATH=$HOME/bin:$PATH
$ chmod +x ~/bin/sudo
$ sudo elevatedCommand
ทดสอบกับ Windows 8 64 บิต
cygstart
วิธีนี้คือใช้ได้กับคำสั่ง / โปรแกรมของ Windows เท่านั้น sudo ls
คุณไม่สามารถทำ SUDO สำหรับ CygWin นั้นเรียบร้อย แต่ก็ยังขาดsudo
คำสั่งที่ดีอยู่
sudo ls
ใน Cygwin ในสถานการณ์ใดบ้าง
sudo
สำหรับ CygWin เพื่อรันคำสั่ง Windows หรือ CygWin มันมีประโยชน์มากสำหรับฉัน แต่วิธีการที่ใช้ประโยชน์ได้มากกว่าที่ฉันพบคือชุดหุ้มสคริปต์สำหรับ SUDO สำหรับ CygWin ที่ฉันพัฒนาขึ้น: superuser.com/questions/741345/… (ยังอยู่ในเบต้า แต่ดูเหมือนว่าจะใช้งานได้) sudo net start vncserver
ด้วยคุณสะดวกสบายสามารถสั่งซื้อสิ่งที่ต้องการ
/bin
และจาก/usr/bin
PATH
มันไม่ประสบความสำเร็จวิงวอน emacs: ShellExecute(NULL, "runas", "C:\cygwin64\bin\emacs-w32.exe", "(null)", "(null)", 1)
แต่แล้ว emacs ไม่สามารถหาls
สำหรับเช่นแม้หลังจากการโต้ตอบการฟื้นฟูเส้นทางโดยใช้M-x dired
(setenv ...)
มีปัญหาเส้นทางที่เชื่อถือได้ที่นี่หรือไม่?
การสร้างคำตอบของ dotancohenฉันใช้นามแฝง:
alias sudo="cygstart --action=runas"
ใช้งานได้อย่างมีเสน่ห์สำหรับโปรแกรมภายนอก (ไม่ใช่ shell built-ins)
sudo chown User:Group <file>
Sudo (ยกระดับ) สำหรับ Windows ™
ฉันทำงานเป็นจำนวนมากบนบรรทัดคำสั่งใน Windows ™
ใน Cygwin ฉันเชื่อว่าคุณสามารถรันคำสั่งรูทด้วยsu -c /the/cmd
สำหรับ sudo เองภายในระบบไฟล์ของ Windows ™เพื่อยกระดับสิทธิ์ของผู้ใช้จากบรรทัดคำสั่งหากคุณเป็นผู้ดูแลระบบสิ่งนี้จะใช้ได้ผลดีสำหรับคุณ มิฉะนั้นให้ใช้ Runas และรับรหัสผ่านของผู้ดูแลระบบ;)
ตอนนี้ฉันจำไม่ได้ว่าเราได้รับรหัสนี้จากที่ใด ฉันหวังว่ามันจะช่วย
BTW, gcc-mingw32
แพคเกจที่เราใช้ในการรวบรวมนี้คือ
$ i586-mingw32msvc-gcc sudo.c -o sudo.exe
# Put sudo.exe in /usr/bin or in your windows path (%homedrive%\windows)
#example:
$ sudo vi /cygdrive/c/windows/system32/drivers/etc/hosts
/**
* (sudo for Windows™)
* @filename sudo.c
*/
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <shellapi.h>
#include <wchar.h>
LPWSTR *mergestrings(LPWSTR *left, LPCWSTR right)
{
size_t size = ( 1 + lstrlen(*left) + lstrlen(right) ) * sizeof(LPWSTR*);
if ( *left ) {
LPWSTR leftcopy = _wcsdup(*left);
*left = (LPWSTR)realloc(*left, size);
*left = lstrcpy(*left, leftcopy);
*left = lstrcat(*left, right);
free( leftcopy );
}
else
*left = _wcsdup(right);
return left;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR lpcommand, int nShowCmd)
{
DWORD result = 0x2a;
LPWSTR *argv = NULL;
int argc = 0;
if ( argv = CommandLineToArgvW(GetCommandLineW(), &argc) ) {
if ( argc < 2 ) {
LPWSTR usagemsg = NULL;
usagemsg = *mergestrings(&usagemsg, argv[0]);
usagemsg = *mergestrings(&usagemsg, TEXT(" <command_to_run> [arguments]"));
MessageBox(NULL, usagemsg, TEXT("Usage:"), MB_OK | MB_ICONEXCLAMATION );
LocalFree( argv );
free( usagemsg );
return ERROR_BAD_ARGUMENTS;
}
else {
LPWSTR command = argv[1];
LPWSTR arguments = NULL;
int c;
for ( c = 2; c < argc; c++ ) {
arguments = *mergestrings(&arguments, argv[c]);
arguments = *mergestrings(&arguments, TEXT(" "));
}
result = (DWORD)ShellExecute(NULL, TEXT("runas"), command, arguments, NULL, SW_SHOWNORMAL);
LocalFree( argv );
if ( arguments )
free( arguments );
switch ( result )
{
case 0:
result = ERROR_OUTOFMEMORY;
break;
case 27:
case 31:
result = ERROR_NO_ASSOCIATION;
break;
case 28:
case 29:
case 30:
result = ERROR_DDE_FAIL;
break;
case 32:
result = ERROR_DLL_NOT_FOUND;
break;
default:
if ( result > 32 )
result = 0x2a;
}
}
}
else
result = GetLastError();
if (result != 0x2a) {
LPWSTR errormsg = NULL;
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, result, 0, (LPWSTR)&errormsg, 0, NULL);
MessageBox(NULL, errormsg, TEXT("Error:"), MB_OK | MB_ICONERROR);
LocalFree( errormsg );
return result;
}
else
return NO_ERROR;
}
การปรับปรุงเล็กน้อยในสคริปต์sudo ปลอมของ Peon :
#!/bin/sh
# Drop any option arguments.
while [[ $# -ge 0 && $1 = -* ]]; do
shift
done
"$@"
สคริปต์นี้จะลดตัวเลือกใด ๆ ที่ส่งผ่านไปยัง sudo และดำเนินการคำสั่ง (โดยไม่ยกระดับสิทธิ์) การลดตัวเลือกปรับปรุงความเข้ากันได้บ้าง สคริปต์ตัวตัดคำที่สมบูรณ์ยิ่งขึ้นควรแยกวิเคราะห์ตัวเลือกตามที่ sudo ทำ
แทนที่จะพยายามแทนที่ sudo ด้วย wrapper ที่cygstart --action=runas "$@"
ใช้เพียงแค่ใช้sudo wrapper ปลอมนี้แล้วเรียกใช้สคริปต์การติดตั้งของคุณเอง (หรือสิ่งที่คุณพยายามเรียกใช้ที่ใช้ sudo) ด้วยสิทธิ์ระดับสูง