44

Because there's no sudo command in Cygwin, scripts that I want to run fail with

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

What's the standard way for getting around this? Editing the scripts to remove sudo? Getting some sudo-like tool for Windows?

9 Answers9

36

One way is to create a fake "sudo" command with the following content:

#!/usr/bin/bash

"$@"

This will allow the install.sh to continue, because sudo is found.

This doesn't elevate privileges like real sudo does. If you really need elevated privileges start cygwin shell with from an account with administrative privileges (XP) or r-click on cygwin.bat and "run as administrator" (Vista,Win7)

matt wilkie
  • 5,324
Peon
  • 791
29

I found the answer on the cygwin mailing list. To run command with elevated privileges in Cygwin, precede the command with cygstart --action=runas like this:

$ cygstart --action=runas command

This will open a Windows dialogue box asking for the Admin password and run the command if the proper password is entered.

This is easily scripted, so long as ~/bin is in your path:

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

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

Tested on 64-bit Windows 8.

dotancohen
  • 11,720
10

I wrote the (rather simple) TOUACExt for SUDO for CygWin, a pre-beta shell script automation that approaches to the behavior of classical sudo for Linux:

  • Open and closes automatically sudoserver.py when needed.
  • Requests UAC Elevation Prompt.

Installation requires copying the four .sh scripts to some path directory, creating an alias and just a few more steps detailed in the thread.

The results: you type a single sudo YourCommand and you get the output of it, without having to worry about the rest of the process.

5

Building on dotancohen's answer I'm using an alias:

alias sudo="cygstart --action=runas"

Works as a charm for external programs (not shell built-ins, though):

sudo chown User:Group <file>
thoni56
  • 185
5

Sudo (Elevate) for Windows™

I do a lot of work on the command line in Windows™.

In Cygwin itself I believe you can run a root command with su -c /the/cmd as for sudo itself within Windows™ file-system elevating the user's permissions from the command line, If you are an administrator, this will work great for you. Otherwise, use runas and get admin's pass ;).

Now I cannot remember where we got this code but here it is. I hope it helps.

BTW, the package we use to compile this was 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;
}
tao
  • 1,445
3

A slight improvement on Peon's fake sudo script:

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

"$@"

This script silently drops any options passed to sudo and executes the command (without actually elevating the privileges). Dropping the options improves compatibility somewhat. A more complete wrapper script should actually parse options the same way sudo does.

Instead of trying to replace sudo with a wrapper that does cygstart --action=runas "$@", just use this simple fake sudo wrapper and run your install script itself (or whatever you're trying to run that uses sudo) with elevated privileges.

1

I've been using cygwin-sudo as a drop-in replacement for UNIX/Linux's sudo.

Based on the same principals but one can remain within your current window.

phdye
  • 21
1

In scripts which can run on linux or windows (cygwin) you can alias out sudo in the script itself:

# Alias sudo to do nothing on windows
if ! $(type -P sudo) 
then
  shopt -s expand_aliases
  alias sudo=""
fi
meesern
  • 141
1

You can run sudo but may require options. If you know the user/group/ Active Dir environment you can supply those as options.

Here is a quick alias or you can "sudo" shell script in common PATH as previous example.

alias sudo='runas /noprofile /user:Administrator $@'  
alias sudo-='runas /profile /env /user:Administrator $@'

Before you can use "sudo" you need a running/enabled windows service called "seclogon".

cmd /c 'sc config seclogon start=auto'
cmd /c 'sc start seclogon'

or use powershell in following link: How do I enable services on a Windows computer via a command line?

PaSe
  • 31
  • 1