web-dev-qa-db-fra.com

Il n'y a pas de commande 'Sudo' dans Cygwin

Parce qu'il n'y a pas de commande Sudo dans Cygwin , les scripts que je souhaite exécuter échouer avec

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

Quel est le moyen standard pour contourner cela? Modification des scripts pour supprimer Sudo? Obtenir un outil de type Sudo- pour Windows?

41
Jason Sundram

J'ai écrit le (plutôt simple) TOUACExt pour Sudo pour CygWin , a Automatisation de script Shell pré-bêta qui aborde le comportement de classique Sudo pour Linux:

  • S'ouvre et se ferme automatiquement sudoserver.py si nécessaire.
  • Requêtes UAC invite d'élévation.

L'installation nécessite la copie des quatre scripts .sh dans un répertoire de chemin, la création d'un alias et quelques étapes supplémentaires décrites dans la discussion.

Les résultats : vous tapez un seul Sudo YourCommand et vous en obtenez le résultat, sans avoir à vous soucier du reste du processus.

8

Une solution consiste à créer une fausse commande "Sudo" avec le contenu suivant:

#!/usr/bin/bash

"$@"

Cela permettra au install.sh de continuer, car Sudo est trouvé.

Cela n'élève pas les privilèges comme le fait le vrai Sudo. Si vous avez vraiment besoin de privilèges élevés, démarrez cygwin Shell avec un compte doté de privilèges d’administration (XP) ou cliquez avec le bouton droit sur cygwin.bat et exécutez "en tant qu’administrateur" (Vista, Win7)

35
Peon

J'ai trouvé la réponse sur sur la liste de diffusion de cygwin . Pour exécuter command avec des privilèges élevés dans Cygwin, faites précéder la commande avec cygstart --action=runas comme ceci:

$ cygstart --action=runas command

Ceci ouvrira une boîte de dialogue Windows demandant le mot de passe de l'administrateur et exécutera la commande si le mot de passe correct est entré.

Ceci est facilement scripté, tant que ~/bin est dans votre chemin:

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

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

Testé sous Windows 8 64 bits.

21
dotancohen

En me basant sur la réponse de dotancohen , j'utilise un alias:

alias Sudo="cygstart --action=runas"

Fonctionne comme un charme pour les programmes externes (mais pas les fonctions intégrées de Shell):

Sudo chown User:Group <file>
5
thoni56

Sudo (Elevate) pour Windows ™

Je travaille beaucoup sur la ligne de commande sous Windows ™.

Dans Cygwin lui-même, je pense que vous pouvez exécuter une commande racine avec su -c /the/cmd comme pour Sudo lui-même dans le système de fichiers Windows ™ en élevant les autorisations de l'utilisateur depuis la ligne de commande. Si vous êtes un administrateur, cela fonctionnera très bien pour vous. Sinon, utilisez les runas et obtenez le passe administrateur;).

Maintenant, je ne me souviens plus où nous avons obtenu ce code, mais le voici. J'espère que ça aide.

En passant, le paquet que nous avons utilisé pour le compiler était 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;
}
3
tao

Une légère amélioration sur le scriptfake Sudoscript:

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

"$@"

Ce script supprime en silence toutes les options transmises à Sudo et exécute la commande (sans élever réellement les privilèges). Supprimer les options améliore quelque peu la compatibilité. Un script d'encapsulation plus complet devrait en réalité analyser les options de la même manière que Sudo.

Au lieu d'essayer de remplacer Sudo par un wrapper doté de cygstart --action=runas "$@", utilisez simplement ce simplefake Sudowrapper et exécutez votre script d'installation lui-même (ou tout ce que vous essayez d'exécuter. utilise Sudo) avec des privilèges élevés.

2
Gene Pavlovsky