1

I am trying to write a script to edit systemd files.

On the CLI I can use the command:

sudo systemctl edit test.service

That opens a text editor, I make the changes and save no problems.

In a bash script I am trying to use the command:

sudo cat > /etc/systemd/system/test.service.d/override.conf <<EOF
[Service]
ExecStartPre=/sbin/iw dev wlan0 interface add ap0 type __ap
EOF

It doesn't work because I don't have the right permissions.

I can then run the command:

sudo touch /etc/systemd/system/test.service.d/override.conf

and that works.

If I then run again:

sudo cat > /etc/systemd/system/test.service.d/override.conf <<EOF
[Service]
ExecStartPre=/sbin/iw dev wlan0 interface add ap0 type __ap
EOF

It also fails on permissions.

As far as I can see, this seems to be an issue with the:

sudo cat > somefile << EOF
some file text
EOF

command sequence. sudo should break through any permission issues, but doesn't in this case.

Is there a solution??

4 Answers 4

1

This question is not really Pi specific, but there is a solution; viz do all your work on a temporary file. Following is an example I have used.

#!/bin/bash
# script to customise ssmtp
# 2017-08-12

# copy sed script to a temporary file
cat << EOF > /tmp/sedscr
/^\s*index/s/index/index index.php/
/^\s*location \//,/^\s*}/ {
/^\s*location \//,/^\s*}/s/ =404/ \/index.php\?\$args =404/
}
/location ~ \\\\.php/i\\
    # insert from Derek Molloy. “Exploring Raspberry Pi.”\\
    location ~ \\\.php$ {\\
       fastcgi_pass unix:/var/run/php5-fpm.sock;\\
       fastcgi_index index.php;\\
       include fastcgi_params;\\
       fastcgi_param SCRIPT_FILENAME \$document_root/\$fastcgi_script_name;\\
    }

EOF

CONFIG_FILE='/etc/nginx/sites-available/default'

# Check/create Backup Config File
if [ ! -e $CONFIG_FILE.orig ]; then
    sudo cp $CONFIG_FILE $CONFIG_FILE.orig
fi

sed -f /tmp/sedscr $CONFIG_FILE >/tmp/nginx_sites
# sed -f /tmp/sedscr $CONFIG_FILE

# copy modified files from /tmp
sudo cp /tmp/nginx_sites $CONFIG_FILE
3
  • I haven't seen that approach in any other answers but it looks like a good option. I can create the file I want in the ~ dir and then sudo mv it to where it needs to be.
    – dazz
    Sep 30, 2018 at 8:52
  • That does mean I need to chown and chmod the final file but the code is easy to read.
    – dazz
    Sep 30, 2018 at 9:00
  • @dazz it is difficult to generalise. Every time I modify a system file I make a backup (which is good practice) and it is much easier to test/verify on a copy, but what you have to do after depends on the files. The example I posted was one of a set of scripts I developed to configure a fresh install to my preferred settings - useful when going from Jessie to Stretch. This is not that uncommon - the book by Derek Molloy mentioned has similar examples. Unfortunately developing/testing these scripts can be time consuming and sed does take quite a bit of learning.
    – Milliways
    Sep 30, 2018 at 11:34
2

OK I found this answer:

All redirections (including >) are applied before executing the actual command. In other words, your shell first tries to open /etc/php5/apache2/php.ini for writing using your account, then runs a completely useless sudo cat.

here: Redirection

EDIT

Based on @Milliways answer, I have applied the following to a script I have written. This code creates a file in the home folder, then moves it to the required folder. Ownership and permissions are set to suit.

#Create the file in the home dir
cat > ~/12-ap0.network <<EOF
[Match]
Name=ap0
[Network]
Address="$ap0_IP"
DHCPServer=yes
IPForward=no
EOF
#move it to where it needs to be
sudo mv ~/12-ap0.network /etc/systemd/network/12-ap0.network
#set the ownership and permissions
sudo chown root:root /etc/systemd/network/12-ap0.network
sudo chmod 777 /etc/systemd/network/12-ap0.network

This adds just one extra line (mv ...) to the code.

0
1

To be clear you should write the solution into your answer instead of linking to it:

rpi ~$ sudo bash -c 'cat > /etc/systemd/system/test.service.d/override.conf <<EOF
[Service]
ExecStartPre=/sbin/iw dev wlan0 interface add ap0 type __ap
EOF'

Consider the two ' character. Because of formating I couldn't put this in a comment.

0

This happens because redirections are not handled by the command (sudo cat in your case), but by the shell running your script. Since the shell is not being run as root, it doesn't have the permissions to open the file.

A typical workaround is

sudo tee /etc/systemd/system/test.service.d/override.conf > /dev/null <<EOF
your text
EOF

The difference is that tee doesn't rely on redirections but actually opens the file by name.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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