Running Bash Script as root with non root script section
I have a bash script that needs to run as root to accomplish a task in this case it is to make the validator take a snapshot of the Helium blockchain.
I have edited the /etc/sudoers file to allow me to run this script as root. This works fine.
useraccount ALL=(ALL:ALL) NOPASSWD:/home/useraccount/validator_data/snapshotmaker.sh
The command in the script is as follows:
sudo docker exec validator miner snapshot take /var/data/$dtt
after this, the command generates a file like this '30-10-2021T233752.bin'.
My next step is to take this file and copy it to IPFS so I can share it. The command to do this is:
ipfs files cp /ipfs/$(ipfs add -Q $localfile) $ip
At the moment I get the following error:
Error: no IPFS repo found in /root/.ipfs. please run: 'ipfs init'
This is because it is trying to run it as root when the configuration is in my useraccount.
I have tried to switch accounts in the middle of the script but it seems to kill it.
So my question is how to run the IPFS command as my original user from within the root script.
My Bash Scrip:
#!/bin/bash
dt=$(date '+%d-%m-%YT%H%M%S');
dtt="${dt}.bin"
a='/var/data/'
c="${a}${dt}.bin"
echo "${c}"
sudo docker exec validator miner snapshot take /var/data/$dtt
localfile="/home/useraccount/validator_data/${dt}.bin"
echo "LocalFile: ${localfile}"
ip=" /Helium/Snapshots/2021/${dt}.bin"
echo "IPFS Location: ${ip}"
sleep 2
if [ -f "$localfile" ]; then
echo "$localfile exists."
sudo chown useraccount $localfile
whoami
su - useraccount
whoami
ipfs files cp /ipfs/$(ipfs add -Q $localfile) $ip
#ipfs files cp /ipfs/$(ipfs add -Q <local-file>) "/Helium/Snapshots/2021/<dest-name>"
else
echo "$localfile does not exist."
fi
The output is as follows:
/var/data/31-10-2021T005728.bin
ok
LocalFile: /home/useraccount/validator_data/31-10-2021T005728.bin
IPFS Location: /Helium/Snapshots/2021/31-10-2021T005728.bin
/home/useraccount/validator_data/31-10-2021T005728.bin exists.
root
And then it dies.
If I remove the su
line then I get the root issue as mentioned at the top of this post.
Hoping someone can help.
I made a 'dry run' test without docker
and whatever you do in it and without ipfs
. The method should work for you with the real programs after some tweaks.
-
Run the shellscript
scrip
as your normal user, not withsudo
. -
Edit the script to change from 'tester' in my demo to your user-name.
-
Edit the exact command lines that need
sudo
without password withvisudo
,$ LANG =C sudo tail -n2 /etc/sudoers %tester ALL=NOPASSWD: /usr/sbin/docker exec validator miner snapshot take /var/data/tmpfil %tester ALL=NOPASSWD: /usr/bin/chown tester /home/tester/validator_data/tmpfil
- It is important to have a fixed name of the file for the sudo operations. After that it can be given a name that depends on the time.
- Check the location of the docker executable (maybe not in
/usr/sbin
).
My modified script scrip
:
#!/bin/bash
if [ "$(whoami)" != "tester" ]
then
echo "run as 'tester'"
exit
fi
dt=$(date '+%d-%m-%YT%H%M%S');
dtt="${dt}.bin"
a='/var/data/'
c="${a}${dt}.bin"
echo "${c}"
sudo /usr/sbin/docker exec validator miner snapshot take /var/data/tmpfil
if [ -f "/home/tester/validator_data/tmpfil" ]; then
ls -l "/home/tester/validator_data/tmpfil"
sudo /usr/bin/chown tester "/home/tester/validator_data/tmpfil"
mv "/home/tester/validator_data/tmpfil" "/home/tester/validator_data/${dt}.bin"
localfile="/home/tester/validator_data/${dt}.bin"
echo "LocalFile: ${localfile}"
ls -l "${localfile}"
ip=" /Helium/Snapshots/2021/${dt}.bin"
echo "IPFS Location: ${ip}"
sleep 2
echo "$localfile exists."
whoami
/usr/local/bin/ipfs files cp /ipfs/$(/usr/local/bin/ipfs add -Q $localfile) $ip
#ipfs files cp /ipfs/$(ipfs add -Q <local-file>) "/Helium/Snapshots/2021/<dest-name>"
else
echo "$localfile does not exist."
fi
A script pretending to be the docker
command line:
#!/bin/bash
if [ "$EUID" == "0" ]
then
echo "docker's world" > "/home/tester/validator_data/tmpfil"
chown root:root "/home/tester/validator_data/tmpfil"
echo "ok"
else
echo "run with sudo"
fi
Demo run:
tester@lenovo-v130:~$ LANG=C ./scrip
/var/data/01-11-2021T051748.bin
ok
-rw-r--r-- 1 root root 15 Nov 1 05:17 /home/tester/validator_data/tmpfil
LocalFile: /home/tester/validator_data/01-11-2021T051748.bin
-rw-r--r-- 1 tester root 15 Nov 1 05:17 /home/tester/validator_data/01-11-2021T051748.bin
IPFS Location: /Helium/Snapshots/2021/01-11-2021T051748.bin
/home/tester/validator_data/01-11-2021T051748.bin exists.
tester
./scrip: line 34: ipfs: command not found
./scrip: line 34: ipfs: command not found