Không có lệnh 'sudo' trong Cygwin


41

Vì không có lệnh sudo trong Cygwin , các tập lệnh mà tôi muốn chạy không thành công với

./install.sh: line N: sudo: command not found

Cách tiêu chuẩn để giải quyết vấn đề này là gì? Chỉnh sửa tập lệnh để loại bỏ sudo? Bắt một số sudocông cụ giống như cho Windows?


@dotancohen, tôi hy vọng tôi chọn đúng.
Jason Sundram

Có vẻ như một giải pháp tốt cho tôi! Hỗ trợ Cygwin đã trở nên tốt hơn trong năm năm qua!
dotancohen 30/03/2015


@Benj, tôi tự hỏi tại sao câu hỏi đó cũng không được di chuyển ở đây.
Jason Sundram

@JasonSundram thực sự. Hãy cho tôi biết nếu câu trả lời được di chuyển, sau đó tôi sẽ cập nhật liên kết.
7:51

Câu trả lời:


8

Tôi đã viết TOUACExt (khá đơn giản) cho SUDO cho CygWin , một trình tự động hóa kịch bản shell tiền beta tiếp cận hành vi của cổ điển sudo đối với Linux:

  • Mở và đóng tự động sudoserver.py khi cần.
  • Yêu cầu Nhắc độ cao UAC .

Cài đặt yêu cầu sao chép bốn .shtập lệnh vào một số thư mục đường dẫn, tạo bí danh và chỉ một vài bước chi tiết trong luồng.

Kết quả : bạn gõ một lần duy nhất sudo YourCommandvà bạn nhận được đầu ra của nó, mà không phải lo lắng về phần còn lại của quá trình.


35

Một cách là tạo một lệnh "sudo" giả với nội dung sau:

#!/usr/bin/bash

"$@"

Điều này sẽ cho phép install.shtiếp tục, bởi vì sudo được tìm thấy.

Điều này không nâng cao đặc quyền như sudo thực sự. Nếu bạn thực sự cần các đặc quyền nâng cao, hãy khởi động shell Cygwin bằng một tài khoản có đặc quyền quản trị (XP) hoặc nhấp chuột vào cygwin.bat và "chạy với tư cách quản trị viên" (Vista, Win7)


5
Chỉ tò mò từ một người không nói trôi chảy bash: Tại sao điều này hoạt động? Trang này không nói bất cứ điều gì về $@việc làm bất cứ điều gì sudogiống như. Thay vào đó chỉ là tất cả các đối số cho kịch bản. Và các trích dẫn xung quanh nó có thừa không trong trường hợp đó? Mặt khác, nếu bạn thực hiện sudo foo barthì nó sẽ thực thi "foo bar"như một lệnh duy nhất có thể không tồn tại do nỗi sợ phi lý về không gian trên các hệ thống giống như UNIX.
Joey

7
@Johannes: "$@"(khi trích dẫn kép) hoạt động khác với "$*": nó mở rộng thành một từ riêng cho mỗi biến vị trí. Ví dụ: Nếu $1 == "foo bar"$2 == "baz", sau đó "$@""foo bar" baz- một từ cho mỗi tham số (không giống như "$*"kết quả "foo bar baz"là một từ). Xem hướng dẫn sử dụng bash, phần Thông số , tiểu mục Thông số đặc biệt . Kết quả cuối cùng của kịch bản của Peon là nó thực thi các đối số của nó chính xác như chúng đã được thông qua.
grawity

1
À, được rồi Và sudophần nào đi vào? Đoạn trích trên không làm gì từ xa theo hướng đó, phải không?
Joey

2
@Johannes: Trong Unix, một người thực sự sudosẽ nâng cao đặc quyền từ người phàm đến roottrước khi chạy lệnh. Trong Cygwin, không có điều đó, vì vậy tập lệnh giả của Peon (mà bạn phải đặt tên sudo) chỉ chạy lệnh trực tiếp mà không thay đổi đặc quyền của nó. (Điều này có nghĩa là bạn có thể cần phải chạy ./install.shvới tư cách Quản trị viên.)
grawity

2
@grawity: runasnên hoạt động, nó không phụ thuộc vào UAC và tự nhắc mật khẩu. Tôi chỉ bối rối tại sao kịch bản trong câu trả lời dường như không làm được cái tên mà tôi cho là mục tiêu. Xin lỗi vì sự ngu ngốc của tôi ;-)
Joey

21

Tôi tìm thấy câu trả lời trong danh sách gửi thư của Cygwin . Để chạy commandvới các đặc quyền nâng cao trong Cygwin, hãy đặt trước lệnh cygstart --action=runasnhư sau:

$ cygstart --action=runas command

Điều này sẽ mở một hộp thoại Windows yêu cầu mật khẩu Quản trị viên và chạy lệnh nếu nhập mật khẩu phù hợp.

Điều này dễ dàng được viết kịch bản, miễn ~/binlà trong đường dẫn của bạn:

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

$ PATH=$HOME/bin:$PATH
$ chmod +x ~/bin/sudo
$ sudo elevatedCommand

Đã thử nghiệm trên Windows 8 64 bit.


5
Vấn đề với cygstartphương pháp là nó chỉ hoạt động cho các lệnh / chương trình Windows. Bạn không thể làm sudo ls. SUDO cho CygWin là gọn gàng, nhưng vẫn thiếu một số sudolệnh tốt trong đó.
Sopalajo de Arrierez

Cảm ơn bạn, Sopalajode. Trong tình huống nào bạn cần sử dụng sudo lstrong Cygwin?
dotancohen

3
Ồ, không, @Dotancohen, đó chỉ là một ví dụ. Bạn có thể sử dụng sudocho CygWin để chạy bất kỳ lệnh Windows hoặc CygWin nào. Nó rất hữu ích cho tôi. Nhưng phương pháp thực tế hơn mà tôi đã tìm thấy là trình bao bọc kịch bản này cho SUDO cho CygWin tôi đã phát triển: superuser.com/questions/741345/ ((vẫn ở bản Beta, nhưng dường như vẫn hoạt động). Với nó, bạn có thể thoải mái đặt hàng những thứ như sudo net start vncserver.
Sopalajo de Arrierez

@SopalajodeArrierez: Điều đó hoàn toàn tuyệt vời! Cảm ơn bạn cho bài viết và các liên kết.
dotancohen

tò mò, dải này ra /bin/usr/bintừ PATH. Nó thực hiện thành công gọi emacs: ShellExecute(NULL, "runas", "C:\cygwin64\bin\emacs-w32.exe", "(null)", "(null)", 1)nhưng sau đó emacs không thể tìm thấy , lsví dụ M-x dired, ngay cả sau khi khôi phục tương tác PATH bằng cách sử dụng (setenv ...). Có một vấn đề đường dẫn đáng tin cậy ở đây?
BaseZen

5

Dựa trên câu trả lời của dotancohen Tôi đang sử dụng một bí danh:

alias sudo="cygstart --action=runas"

Hoạt động như một nét duyên dáng cho các chương trình bên ngoài (mặc dù không phải là vỏ dựng sẵn):

sudo chown User:Group <file>

3

Sudo (Nâng cao) cho Windows ™

Tôi làm rất nhiều công việc trên dòng lệnh trong Windows ™.

Trong chính Cygwin, tôi tin rằng bạn có thể chạy một lệnh gốc với su -c /the/cmdchính sudo trong hệ thống tệp Windows ™ nâng cao quyền của người dùng từ dòng lệnh, Nếu bạn là quản trị viên, điều này sẽ rất tốt cho bạn. Nếu không, hãy sử dụng runas và nhận thông qua của quản trị viên;).

Bây giờ tôi không thể nhớ nơi chúng tôi đã nhận được mã này nhưng đây là. Tôi hy vọng nó sẽ giúp.

BTW, gói chúng tôi sử dụng để biên dịch này là 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;
}

5
Mã này là khủng khiếp. Có đầy đủ các lỗi như không kiểm tra giá trị trả về của realloc () trước khi hội thảo hoặc ghi sizeof (LPWSTR *) thay vì sizeof (* LPWSTR) trong đó LPWSTR dường như là một loại con trỏ và không muốn lấy kích thước của một ký tự, không phải kích thước của con trỏ Hơn nữa, hoàn toàn không rõ tại sao ví dụ: trường hợp 29 dẫn đến ERROR_DDE_FAIL. Bạn có thể kết luận từ mã tại sao? Tôi không thể và tôi đoán bất cứ ai khác cũng không thể. Xin vui lòng, không đăng mã như vậy trong tương lai.

4
@Mattew: trong tương lai, hãy giúp đỡ cộng đồng bằng cách đăng một phiên bản đã được dọn sạch của đoạn mã bạn không thích.
Erik Allik

Mã không nên trên superuser. Đặt nó trên codereview.se và chỉ cần liên kết nó từ đây.
Ben Voigt

@ user185282: Điểm tốt. Tôi đã đánh giá thấp câu trả lời.
không thể nào quên

Kính gửi tao: Bạn đã viết, "Tôi không thể nhớ nơi chúng tôi có mã này". Bạn đã viết mã này, hoặc người khác đã viết nó?
không thể nào quên

2

Một cải tiến nhỏ trên kịch bản sudo giả của Peon :

#!/bin/sh
# Drop any option arguments.
while [[ $# -ge 0 && $1 = -* ]]; do
  shift
done

"$@"

Kịch bản lệnh này âm thầm loại bỏ bất kỳ tùy chọn nào được chuyển sang sudo và thực thi lệnh (mà không thực sự nâng cao các đặc quyền). Bỏ các tùy chọn cải thiện phần nào khả năng tương thích. Một tập lệnh bao bọc hoàn chỉnh hơn thực sự sẽ phân tích các tùy chọn giống như cách sudo thực hiện.

Thay vì cố gắng thay thế sudo bằng một trình bao bọc cygstart --action=runas "$@", hãy sử dụng trình bao bọc giả đơn giản này và chạy tập lệnh cài đặt của bạn (hoặc bất cứ điều gì bạn đang cố chạy bằng sudo) với các đặc quyền nâng cao.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.