4

I'm working on a Linux Bash script that needs to start as root. At the end of the script, it builds a list of packages. This requires running as user. Then it will move the packages, which needs to run as root again. I have sudo set up, but want to keep the script as generic as possible.

I've tried the following and slight variations of it in the first script to switch from root to user.

su -c - "$USER" "export PKGDEST=/tmp/test/AUR/" 
su -c - "$USER" "pacaur --noconfirm --noedit -cm" "$(< /tmp/test/aur)"

The second line fails to run properly resulting in different errors, depending quote combination and placement. Running the lines within the first script as shown above produced the following error after reading the file /tmp/test/aur :: no targets specified (use -h for help). My preference would be getting this single script method to work properly.

Google, etc. said root, user, root in bash is bad, so tried break it into 3 parts:

  1. The first script runs as root. The problem centers here, can't get it to start the second.
  2. Second script runs as user, starts 3rd script as root with: sudo /bin/bash "$L"/copyaur.sh
  3. Third script, copyaur.sh runs, moving the packages properly but doesn't show as running in the terminal because calls new shell?

Below was ran as su in a user terminal during testing. Prefer using the $USER var in the script.

As su in the terminal, then back to su - $USER, then ls in home lists my normal user name [dom's] contents.

[dom@arch testing]$ echo $USER
dom

[root@arch testing]# echo $USER
dom

[root@arch testing]# pwd
/home/dom/scripts/testing

I get the following results in testing, starting as su in the terminal. Want to get $USER var to work in place of dom.

su -       $USER  home/$USER/scripts/testing/buildaur.sh  - No such file or directory
su --login $USER  home/$USER/scripts/testing/buildaur.sh  - No such file or directory
su -       $USER  home/dom/scripts/testing/buildaur.sh    - No such file or directory
su -      "$USER" home/dom/scripts/testing/buildaur.sh    - No such file or directory
su -      "$USER"                        ./buildaur.sh    - No such file or directory
su -       dom                           ./buildaur.sh    - No such file or directory

su -       dom  ~/scripts/testing/buildaur.sh              - Permission denied
su -      $USER ~/scripts/testing/buildaur.sh              - Permission denied
su --login dom  ~/scripts/testing/buildaur.sh              - Permission denied

su -       dom   /home/dom/scripts/testing/buildaur.sh     - Runs as user, expected
su --login dom   /home/dom/scripts/testing/buildaur.sh     - Runs as user, expected
su -       dom   /home/$USER/scripts/testing/buildaur.sh   - Runs as user, expected

9/19/2014 EDIT TO ADD REQUESTED INFO

Here's part of the script. Still no solution. This latest variation has made it through building the first package from the list before failing. It does however complete the next line, which is the last command in the script. Keep in mind this command works fine outside of using it with the proceeding su -c - "$USER" "pacaur --noconfirm --noedit -cm $(< /tmp/makeiso/aur)"

#!/bin/bash     
##  makeiso.sh must be run as root within /home/"$USER"/makeiso/releng
##  makeiso dependancies: archiso pacaur
#############################################################################

# Accessing an empty variable will yield an error

    set -u

# Check if root
# Print message to user

    echo "Checking if we're running as root"

    if [[ $EUID -ne 0 ]]; then
        echo "This script must be run as root" 1>&2
        exit 1
    fi

# echo for a space 
    echo ""

# If passed root test, send message print message to user

    if [[ $EUID = 0 ]]; then
        echo "Passed root test, proceeding"
        fi

##################################################
##################################################
Line 180 of the script running as root.......
##################################################

# Print message to user

    echo "Copying system configuration files"

    set -x

# Create directory for following command

mkdir -p /tmp/makeiso/

# Create a list of modified config files

    pacman -Qii | awk '/^MODIFIED/ {print $2}' >> /tmp/makeiso/rtmodconfig.list

# Create destination directory for the following command

    mkdir -p "$L"/airootfs/makeiso/configs/rootconfigs

# Copy above list to releng for later use

    cp /tmp/makeiso/rtmodconfig.list "$L"/airootfs/makeiso/configs/rootconfigs/rtmodconfig.list

# Read rtmodconfig.list and copy the modified config files to releng

    xargs -a /tmp/makeiso/rtmodconfig.list cp -t "$L"/airootfs/makeiso/configs/rootconfigs/

# Set makepkg variable to define where to send built packages 

    su -c - "$USER" "export PKGDEST=/tmp/makeiso/AUR" 

# Build AUR packages from list, /tmp/makepkg/aur
#############

    su -c - "$USER" "pacaur --noconfirm --noedit -cm $(< /tmp/makeiso/aur)"

#############

# Copy the prebuilt AUR packages to releng

    cp -R /tmp/makeiso/AUR "$L"/airootfs/makeiso/packages/AUR

Here's the output with set -x. I'm using pacaur to build the packages, which uses cower and makepkg. It seems like either pacaur or makepkg is loosing track of the file with the list of packages to build, and doesn't recognize the package names as commands.

+ su -c - dom 'export PKGDEST=/tmp/makeiso/AUR'
+ su -c - dom 'pacaur --noconfirm --noedit -cm bootinfoscript
cairo-ubuntu
cower
fontconfig-ubuntu
freetype2-ubuntu
gnome-colors-icon-theme
gnome-colors-icon-theme-extras
gnome-icon-theme-xfce
google-chrome
grub-legacy
libxfcegui4
pacaur
package-query
pkgbrowser
ttf-ms-fonts
virtualbox-ext-oracle
vivaldi
xfce4-quicklauncher-plugin'
:: resolving dependencies...
:: looking for inter-conflicts...

AUR Packages  (1): bootinfoscript-0.61-1  

:: Retrieving package(s)...
sudo: no tty present and no askpass program specified
:: Checking bootinfoscript integrity...
==> Making package: bootinfoscript 0.61-1 (Sat Sep 19 22:27:37 PDT 2015)
==> Retrieving sources...
  -> Found bootinfoscript-061.tar.gz
==> Validating source files with md5sums...
    bootinfoscript-061.tar.gz ... Passed
:: Building bootinfoscript package(s)...
==> Making package: bootinfoscript 0.61-1 (Sat Sep 19 22:27:38 PDT 2015)
==> Checking runtime dependencies...
==> Checking buildtime dependencies...
==> Retrieving sources...
  -> Found bootinfoscript-061.tar.gz
==> Validating source files with md5sums...
    bootinfoscript-061.tar.gz ... Passed
==> Extracting sources...
  -> Extracting bootinfoscript-061.tar.gz with bsdtar
==> Removing existing $pkgdir/ directory...
==> Entering fakeroot environment...
==> Starting package()...
==> Tidying install...
  -> Purging unwanted files...
  -> Removing libtool files...
  -> Removing static library files...
  -> Compressing man and info pages...
  -> Stripping unneeded symbols from binaries and libraries...
==> Creating package "bootinfoscript"...
  -> Generating .PKGINFO file...
  -> Generating .MTREE file...
  -> Compressing package...
==> Leaving fakeroot environment.
==> Finished making: bootinfoscript 0.61-1 (Sat Sep 19 22:27:38 PDT 2015)
:: bootinfoscript cleaning skipped
bash: line 1: cairo-ubuntu: command not found
error: no operation specified (use -h for help)
bash: line 3: fontconfig-ubuntu: command not found
bash: line 4: freetype2-ubuntu: command not found
bash: line 5: gnome-colors-icon-theme: command not found
bash: line 6: gnome-colors-icon-theme-extras: command not found
bash: line 7: gnome-icon-theme-xfce: command not found
bash: line 8: google-chrome: command not found
bash: line 9: grub-legacy: command not found
bash: line 10: libxfcegui4: command not found
error: no operation specified (use -h for help)
bash: line 14: ttf-ms-fonts: command not found
bash: line 15: virtualbox-ext-oracle: command not found
bash: line 16: vivaldi: command not found
bash: line 17: xfce4-quicklauncher-plugin: command not found
+ cp -R /tmp/makeiso/AUR /home/dom/makeiso/releng/airootfs/makeiso/packages/AUR
10
  • What OS are you using? Do you have sudo set up?
    – terdon
    Sep 17, 2015 at 22:32
  • I'm running this on Arch Linux and sudo is set up. I'd like to possibly share this script down the road, so I'd like to keep as generic as possible. I edited the op to reflect this.
    – Dom
    Sep 18, 2015 at 2:30
  • Why does building a list of packages requires to be user not root? Are you on NFS?
    – Bichoy
    Sep 18, 2015 at 6:00
  • This is an Arch Linux relate standard, to not build packages as root. In fact makepkg will not run as root. Arch has the AUR, Arch user repository. This repo contains build scripts rather than binary pre built packages. Anyone can contribute, mostly unchecked, so the potential is there for things to go wrong, either in error or malicious. More info: allanmcrae.com/2015/01/replacing-makepkg-asroot
    – Dom
    Sep 18, 2015 at 8:46
  • 1
    It's very hard to understand what you're doing since you don't show your scripts. Could you simplify this to an example script that reproduces the problem? If you need to run a single command as non-root, just use sudo -u user command or su -c command user.
    – terdon
    Sep 18, 2015 at 11:53

2 Answers 2

1

The following worked as needed in my script to switch from root to $USER, then back to root.

sudo -u "$USER" bash << HereTag

command
command
command

# End Here Tag 
HereTag 

To review, I'm starting the script like this:

[user@linuxbox ~]$ su
Password: 
[root@linuxbox user]# ./script.sh

After $ su, echo $USER shows my username. Even though I'm starting the script as root, I am prompted for a password @ sudo -u "$USER" bash.

I'm in the wheel group needing to provide password in suoders file.

I'd like to eventually figure out how to accomplish this without the need for sudo, but this will work for now.

0
su -c "<command to run as user>" $USER

This worked for me when creating an auto installer that you would need to execute with sudo, at the end of my script it needed to switch from root to user in order finish its install cycle

You would use the su command to Switch User.

Then you would use -c to specify the command to be run as non-root user.

Then you would use $USER to specify that you need the script to switch to non-root user.

an example of what worked for me is below.

su -c "npm install && npm audit fix" $USER

Just remember this

  • if you need your bash script to switch from root to user (non-root) you would use su -c "command here" $USER
  • if you need your bash script to switch from user (non-root) to root you would use su -c "command here" $user

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .