Mac terminal : trying to add to /etc/shells - macos

This one works
$ cat /etc/shells
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.
/bin/bash
/bin/csh
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
But this one does not :
sudo -s 'echo /usr/local/bin/zsh >> /etc/shells'
/bin/bash: echo /usr/local/bin/zsh >> /etc/shells: No such file or directory

sudo takes the string as complete command. You should use a shell to interpret your command like this:
sudo sh -c 'echo /usr/local/bin/zsh >> /etc/shells'
This executes sh with root privileges, and sh interprets the string as a shell command including >> as output redirection.

The only thing you really need sudo for is to open the protected file for writing. You can use the tee command to append to the file.
echo /usr/local/bin/zsh | sudo tee -a /etc/shells > /dev/null

Related

Drop from root to user preserving ALL environment variables

The following bash command works to drop down to user privileges, and preserve an environment for the most part:
root#machine:/root# DOLPHIN=1 sudo -E -u someuser bash -c 'echo $DOLPHIN'
1
However, this does not work for all variables, such as PATH, and LD_LIBRARY_PATH:
root#machine:/root# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
root#machine:/root# sudo -E -u someuser bash -c 'echo $PATH'
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
Notice the PATH is different ^
Why is this happening?
Must be some bash mechanics I don't understand...
Looks like this is a workable option:
root#machine:/root# sudo PATH=$PATH LD_LIBRARY_PATH=$LD_LIBRARY_PATH -E -u someuser bash -c 'echo $PATH'
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

Unable to modify /etc/shells on macOS to include brew installed version of bash

I am trying to update my /etc/shells file to include the path to a homebrew installed version of bash which resides at /usr/local/bin/bash
$ sudo echo /usr/local/bin/bash >> /etc/shells returns Permission denied and attempting to manually update is not allowed as it appears to be read-only.
Upon inspecting the file, the permissions are set as follows:
-rw-r--r-- 1 root wheel 179 Feb 21 2017 /etc/shells
So, with this in mind, and after looking at this article about Updating you shell with Homebrew I tried to initiate a shell as the root user and then try command above, i.e:
$ sudo -s
$ echo /usr/local/bin/bash >> /etc/shells
$ chsh -s /usr/local/bin/bash
However, this seems to hang on the first command ($ sudo -s). This spawns a bash process that eats up ~ 70% CPU and nothing happens.
Is there an alternative way one can update the /etc/shells/ file?
An approach to adding to a root-only file is echo /usr/local/bin/bash | sudo tee -a /etc/shells.
– Petesh
Would you be able to explain why that works and the sudo echo /usr/local/bin/bash >> /etc/shells does not though.
The latter doesn't work because the output redirection >> is (tried to be) applied by the shell before the sudo … is executed, and of course the user shell has no permission to do that.
Or you can just use this (I had to do this on macOS Mojave):
sudo sh -c "echo $(which zsh) >> /etc/shells"
chsh -s $(which zsh)

Edit an privileged file via bash

I need to edit an privileged file using bash on Ubuntu 14.04
This simple command is not working:
sudo echo $someText >> $privilegedFile
I get this error:
Permission denied
I have no idea what is wrong with it.
Thanks.
The shell processes the redirection before it runs sudo, so $privilegedFile is still opened using the current user's permissions.
One workaround is to open the file with a program run by sudo rather than using redirections.
echo "$someText" | sudo tee -a "$privilegedFile"
Another is to start an entirely new shell with sudo and execute the full command in that shell.
sudo sh -c "echo '$someText' >> '$privilegedFile'"
You should try this:
sudo sh -c "echo $text >> $file"
do
sudo chmod u+xrw FILE
and
sudo nano FILE
Don't use echo for editing, try nano, gedit or vi.

Update root crontab remotely for many systems by script

I am trying to update the crontab file of 1000+ systems using a for loop from jump host.
The below doesn't work.
echo -e 'pass365\!\n' | sudo -S echo 'hello' >> /var/spool/cron/root
-bash: /var/spool/cron/root: Permission denied
I do have (ALL) ALL in the sudoers file.
This is another solution;
echo 'pass365\!' | sudo -S bash -c 'echo "hello">> /var/spool/cron/root'
The below worked for me.
echo 'pass365\!' | sudo -S echo 'hello' | sudo -S tee -a /var/spool/cron/root > /dev/null
Problem 1: You are trying to send the password via echo to sudo.
Problem 2: You can't use shell redirection in a sudo command like that.
Between the two of these, consider setting up ssh public key authorization and doing
ssh root#host "echo 'hello' \>\> /var/spool/cron/root"
You may eventually get sudo working but it will be so much more pain than this.

Sudo not prompting for password Mac bash script

I am trying to write a script that appends a line to the /etc/hosts, which means I need sudoer privileges. However, if I run the script from the desktop it does not prompt for a password. I simply get permission denied.
Example script:
#!/bin/bash
sudo echo '131.253.13.32 www.google.com' >> /etc/hosts
dscacheutil -flushcache
A terminal pops up and says permission denied, but never actually prompts for the sudo password. Is there a way to fix this?
sudo doesn't apply to the redirection operator. You can use either echo | sudo tee -a or sudo bash -c 'echo >>':
echo 131.253.13.32 www.google.com | sudo tee -a /etc/hosts
sudo bash -c 'echo 131.253.13.32 www.google.com >> /etc/hosts'
What you are doing here is effectively:
Switch to root, and run echo
Switch back to yourself and try to append the output of sudo onto
/etc/hosts
That doesn't work because you need to be root when you're appending to /etc/hosts, not when you're running echo.
The simplest way to do this is
sudo bash -c "sudo echo '131.253.13.32 www.google.com' >> /etc/hosts"
which will run bash itself as root. However, that's not particularly safe, since you're now invoking a shell as root, which could potentially do lots of nasty stuff (in particular, it will execute the contents of the file whose name is in the environment variable BASH_ENV, if there is one. So you might prefer to do this a bit more cautiously:
sudo env -i bash -c "sudo echo '131.253.13.32 www.google.com' >> /etc/hosts"

Resources