Root user/sudo equivalent in Cygwin?

181,895

Solution 1

I answered this question on SuperUser but only after the OP disregarded the unhelpful answer that was at the time the only answer to the question.

Here is the proper way to elevate permissions in Cygwin, copied from my own answer on SuperUser:

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. Create a file ~/bin/sudo with the following content:

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

Now make the file executable:

$ chmod +x ~/bin/sudo

Now you can run commands with real elevated privileges:

$ sudo elevatedCommand

You may need to add ~/bin to your path. You can run the following command on the Cygwin CLI, or add it to ~/.bashrc:

$ PATH=$HOME/bin:$PATH

Tested on 64-bit Windows 8.

You could also instead of above steps add an alias for this command to ~/.bashrc:

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

Solution 2

You probably need to run the cygwin shell as Administrator. You can right click the shortcut and click run as administrator or go into the properties of the shortcut and check it in the compatability section. Just beware.... root permissions can be dangerous.

Solution 3

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

alias sudo="cygstart --action=runas"

Works as a charm:

sudo chown User:Group <file>

And if you have SysInternals installed you can even start a command shell as the system user very easily

sudo psexec -i -s -d cmd

Solution 4

I found sudo-for-cygwin, maybe this would work, it is a client/server application that uses a python script to spawn a child process in windows (pty) and bridges user's tty and the process I/O.

It requires python in windows and Python modules greenlet, and eventlet in Cygwin.

Solution 5

It seems that cygstart/runas does not properly handle "$@" and thus commands that have arguments containing spaces (and perhaps other shell meta-characters -- I didn't check) will not work correctly.

I decided to just write a small sudo script that works by writing a temporary script that does the parameters correctly.

#! /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
Share:
181,895

Related videos on Youtube

Ken Bellows
Author by

Ken Bellows

I'm a dev living outside of Baltimore, mainly focused on web stuff and node.js at this point but with plenty of prior work in Python, Ruby, Java (😔), and like twenty other languages to a lesser extent.

Updated on November 05, 2021

Comments

  • Ken Bellows
    Ken Bellows over 2 years

    I'm trying to run a bash script in Cygwin.

    I get Must run as root, i.e. sudo ./scriptname errors.

    chmod 777 scriptname does nothing to help.

    I've looked for ways to imitate sudo on Cygwin, to add a root user, since calling "su" renders the error su: user root does not exist, anything useful, and have found nothing.

    Anyone have any suggestions?

    • Stefano
      Stefano about 13 years
      hello KenB, could you give us more detail on what script you are trying to run? There is no equivalent to 'sudo' inside a cygwin shell - the rights are the ones from the win user that launched the cygwin shell, so KyleWpppd link is good to avoid errors such as "sudo unknown command". In your case sounds like it's a specific issue with the script you want to execute.
    • Ken Bellows
      Ken Bellows about 13 years
      Honestly, this is an issue long past, and I don't actually remember what the script was. Thanks for the interest, though.
    • Benj
      Benj almost 8 years
  • Nikana Reklawyks
    Nikana Reklawyks over 11 years
    How will that make him root, as he asks ?
  • dotancohen
    dotancohen over 10 years
    In the three years since this question has been asked without a good answer as opposed to this workaround, I've found the correct way to raise permissions for a single command in the extant Cygwin window in the answer below. Thus, it functions exactly like sudo in Linux.
  • josmith42
    josmith42 over 10 years
    Excellent answer. With some tweaks to your bash code (below), I was able to run an elevated command from the command line. Here's the change I needed to make your code work: cat << 'EOF' > ~/bin/sudo\n #!/usr/bin/bash\n cygstart --action=runas "$@"\n EOF (I can't figure out how to insert newlines in this comment, so I've added '\n's to the code) The rest from the PATH=... onward is fine.
  • dotancohen
    dotancohen over 10 years
    @josmith42: Thank you! I don't see the difference between my script and yours. What is the difference?
  • josmith42
    josmith42 over 10 years
    It's mainly the first line: I have cat << 'EOF' > ~/bin/sudo. And I added EOF below the cygstart line to close off the here document.
  • dotancohen
    dotancohen over 10 years
    Oh, I see! If I'm not mistaken, that is your way of writing the file to disk, instead of opening a text editor. Nice, thank you! I did not know how to use heredocs in Bash!
  • user1530318
    user1530318 over 10 years
    $ cat ~/bin/sudo cat: /home/MyName/bin/sudo: No such file or directory What could be the issue there? I have a usr/local/bin and usr/bin in my path
  • dotancohen
    dotancohen over 10 years
    You need to create that file with the contents that you see. The cat command just shows you what I have in the file (i.e. what you need to put in the file).
  • Michael Scheper
    Michael Scheper about 10 years
    Could you reword the answer to make that clear? The answer is very helpful but I, too, was confused by how you presented it.
  • dotancohen
    dotancohen about 10 years
    I have edited the answer to make things clearer for those unfamiliar with Unix concepts and commands. If anything else is unclear, let me know and I'll try to elucidate. Thanks!
  • JeeBee
    JeeBee over 9 years
    This solution doesn't appear to pick up the Cygwin path, only the Windows path, if the command you run is "bash" to get an elevated bash. Luckily you can use the full path still, if you need to e.g., pipe the output of an elevated command through grep, for example.
  • katriel
    katriel over 8 years
    Removing the quotes, i.e., cygstart --action=runas $@ works better for most of my use cases, since I want the command to be able to parse separate arguments.
  • Olivier Grégoire
    Olivier Grégoire about 8 years
    @katriel what is the difference between the quotes version and the no-quotes version? I see it works better for my use cases as well, but I don't understand why.
  • Ken Bellows
    Ken Bellows about 8 years
    @OlivierGrégoire Everything within quotes is treated as a single token by bash, so I expect (haven't tested) that it will try to treat everything in the quotes as the command name, rather than taking the first token as the command and the rest as arguments. Example: cygstart --action=runas "ls /bin" will try to find a command named "ls bin"; cygstart --action=runas ls /bin will instead try to find a command named "ls" and pass it the argument "/bin"
  • deed02392
    deed02392 about 8 years
    @KenB i just tested and I could do for eg sudo taskkill -f -im iexplore.exe with the quoted version. So I'm not sure there is any difference. Someone who really knows Bash could say otherwise though
  • CMCDragonkai
    CMCDragonkai about 8 years
    The problem with this is that it creates a whole new terminal window (usually conhost). The output isn't inlined into the current terminal.
  • CMCDragonkai
    CMCDragonkai about 8 years
    The only way to run things like ls is to wrap it in a long running process like mintty or bash or zsh too. But it all appears in a separate terminal. Which at this point, I could have just opened it via the GUI using ConEMU.
  • Palec
    Palec over 7 years
    Without the quotes, even quoted arguments are split in spaces again, @katriel. With the quotes, "$@" expands to something like "$1" "$2" "$3" ... and without, $@ expands to $1 $2 $3....
  • MemphiZ
    MemphiZ over 7 years
    I'm using this for a while now and it event handles interactive stuff like nano without any problems!
  • Brian White
    Brian White about 7 years
    Regarding the $@ vs "$@" debate... The proper bash way is with the quotes as otherwise spaces within arguments will cause such to become multiple arguments. "$@" is special; see man page. However, it seems that either cygstart or runas do not do things in the bash way and so no option works completely correctly. To verify, compare sudo bash -c 'ls;read' vs sudo bash -c 'ls; read' (note space after semicolon). The first works (and pauses waiting for <enter>) while the second fails. The extra space after the semicolon is breaking the passed command.
  • jjjjjj
    jjjjjj almost 7 years
    Note: command needs to be replaced with the actual command you want to run, and for a noob like me, I missed that...
  • nanker
    nanker about 6 years
    the accepted answer did not work for me on Win7 but this answer worked like a charm. I was able to set up exim-config with elevated privs and then vim-edit the /etc/exim.conf file afterwards. Slick.
  • lcfd
    lcfd about 6 years
    Unfortunately, because of opening into another terminal, piped commands will not work, I wanted to run a netstat -ab | grep ...
  • lowtechsun
    lowtechsun over 5 years
    Worked for me on Win10 64. Had to change ownership of files downloaded from a server with rsync. chown --changes --verbose --recursive [USER] /cygdrive/c/[PATH TO FOLDER]/*. Without it I could not access the rsynced folders and files.
  • Edwin Pratt
    Edwin Pratt over 5 years
    The only minor problem is that you can't tell if it is opened as administrator.
  • Brian White
    Brian White about 4 years
    How does cygstart --wait --action=runas $mintty /bin/bash "$0" "$@" not break if there are spaces in an argument? It always did for me when passing such through cygstart/runas.
  • Erik Bennett
    Erik Bennett about 3 years
    So, the normal "switch user" (su) program allows one to pick the target user. Is there any way to do that cygwin style using this method?
  • Phil Goetz
    Phil Goetz almost 3 years
    At present, this seems only able to run Windows executables, not the Unix executables provided in cygwin. E.g., "sudo cpan" and "sudo which cpan both produce "Unable to start 'C:\cygwin64\bin\cpan': There is no application associated with the given file name extension."
  • seanahern
    seanahern over 2 years
    Watch your chmod. It should e chmod +x, not chmod +X. Case matters to chmod.