12

In a small bash script I'm running I am attempting to chown a new directory that is created. I've added:

sudo chown $USER:$USER /var/www/$sitename
sudo chmod 775 /var/www/$sitename

after the line where I mkdir (sudo mkdir /var/www/$sitename).

For some reason the chown is not executing. I can execute it manually but when written in the file it doesn't work. I have noticed that "chown" is not highlighted in the same color as "mkdir" and "chmod" but I can't figure out my problem.

Why doesn't chown work here?

Is it an issue with $USER:$USER?

EDIT Here is the full script. How would I chown the file to whichever non root user executed the script?

#!/bin/sh
#!/bin/bash
# New Site

cd /etc/apache2/sites-available/
echo "New site name (test.my):"
read sitename
echo "<VirtualHost *:80>

        ServerAdmin admin@$sitename

    ServerName $sitename

        ServerAlias $sitename

    DocumentRoot /var/www/$sitename

        <Directory />
                Options FollowSymLinks
                AllowOverride All
        </Directory>
        <Directory /var/www/$sitename>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined


</VirtualHost>" > $sitename.conf
sudo mkdir /var/www/$sitename
sudo chown $USER:$USER /var/www/$sitename
echo USER is $USER
sudo chmod 775 /var/www/$sitename
sudo a2ensite $sitename.conf
sudo apachectl restart
echo "New site created"
10
  • 1
    Is there a group named $USER? getent group $USER
    – Cyrus
    Feb 5, 2015 at 20:20
  • 1
    $USER variable is set during interactive login. How do you run your script - from login session or using cron or from daemon?
    – myaut
    Feb 5, 2015 at 20:31
  • 1
    Check if the USER variable is even seen by the script. If you add a line to your script that says echo USER is $USER, what does it print out? Feb 5, 2015 at 22:12
  • 1
    @BrassApparatus I guess technically you'd want to use $(id -nu):$(id -ng) to get the user and the group.
    – Celada
    Feb 7, 2015 at 10:39
  • 1
    Try using $U or anything else, but not $USER, because this variable is special for sudo. See man sudo section ENVIRONMENT.
    – ott--
    Feb 7, 2015 at 14:24

5 Answers 5

10

If for some reason, $USER is not set, you can use the id command to obtain the identity of the real user. So the first time you use the $USER variable, you can use the shell expansion to supply a default value. Change the chown line in your script to:

sudo chown "${USER:=$(/usr/bin/id -run)}:$USER" "/var/www/$sitename"

If USER is empty or unset when this is run, bash will set the USER variable to the output of /usr/bin/id -run.

5

When I calling my script with sudo it would set $USER to root.

$ sudo ./myscript.sh

I tried the chown ${USER:=$(/usr/bin/id -run)}:$USER /var/www/$sitename but it would still return root.

I found if I used who with awk I was able to get the current user that called the script with sudo.

currentuser=$(who | awk '{print $1}')}
chown -R $currentuser:$currentuser /var/www/$sitename`
3
  • 1
    To prevent setting currentuser (sometime) with multiline users, use $(who | awk 'NR==1{print $1}') instead. Feb 12, 2018 at 12:31
  • I am trying to change /usr to my user: chown -R $currentuser:$currentuser /usr - does not work - still shows root:root
    – Sam-T
    Dec 23, 2019 at 3:34
  • (1) who is not guaranteed to produce any output.  (2) If it does, there is no guarantee that the first line of output identifies the current user.  What if somebody ssh’ed into your system?  What if you are ssh’ed into some other system? (3) logname seems to be more reliable. Jun 27 at 6:16
2

In order to simplify the problem and since your are getting the variable sitename, why don't you read a username variable?

With that you'd make sure that the script execution is not dependent on the environmental variables made available the way the script is executed.

1

The accepted answer by @tim-cutts would not work if you call the script itself with sudo:

sudo ./myscript.sh

A more simple version of this answer would be to use logname:

curuser=$(logname)
chown $curuser:$curuser /var/www/$sitename
New contributor
Hogcryat is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
6
  • Note that the script in the question is executed with /bin/sh as the shell. If that shell does not set the USER variable, Tim's code would call id to figure out the username. Under what circumstances would logname get the username right and id get it wrong? Would the shell need to set USER to the wrong username for that to be the case? What do you mean by "not work"? Are you expecting the user to be reported as root or the invoking user in your example?
    – Kusalananda
    Jun 25 at 17:55
  • Sorry for the tone in my last comment (I just re-read it). What I was fishing for is merely an explanation of the problem that you see and an explanation of your solution, taking into account that since you refer to Tim's answer, you would need to clarify the circumstances that his answer gets it wrong and what "wrong" actually means.
    – Kusalananda
    Jun 25 at 18:15
  • @Kusalananda: The explanation is right there in the first paragraph. OK, yes, the script in the question contains multiple sudo commands, so it’s ‘ ‘clearly’ ’ meant to be run by a non-root user. But what if somebody inadvertently runs the script itself under sudo? Then the id command (as used by Tim Cutts) would return “root” and not, as (presumably) desired, the name of the logged-in user. Jun 25 at 22:40
  • @Kusalananda: OK, now it’s my turn to re-read and re-write/clarify.  Hogcryat’s answer (above) links to Eric James Deiter’s answer, and the explanation is in the first paragraph of Eric’s answer. Jun 26 at 2:08
  • @Kusalananda it is just as Reinstate Monica says. It is an improvement to Eric's answer in the case the script was called with sudo (which I know is not the question's original intention). I would have liked to comment under Eric's answer but I don't have enough reputation.
    – Hogcryat
    Jun 26 at 18:37
0

There is only a tiny fault I think. sudo opens a new shell for executing the command and after sudo the user is root. So maybe you should use something like this:

MYUSER=$USER

sudo chown $MYUSER:$MYUSER

as i think MYUSER is not systemspezific overwritten and shall work.

1
  • 2
    The variable is evaluated before the command is executed, so your suggested alternative would make no difference. (Try it with echo chown... and see.)
    – roaima
    Jul 9, 2016 at 13:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.