Bash: sourcing file as user from script - linux

I am creating a script meant to be run as superuser that reads a file and runs a number of scripts on behalf of all users. The important bit is this:
sudo -u $user -H source /home/$user/list_of_commands
However, whether I encose the command with quotesor not, this fails with:
sudo: source /home/user/list_of_commands: command not found
I have even tried with the . bash builtin:
sudo: . /home/user/list_of_commands: command not found
Of course running source outside a sudo environment works. I thought there might be a PATH problem, and I tried to bypass it by providing the full path to source. However, I cannot find the executable: which source returns which: no source in (/usr/local/sbin:usr/local/bin:usr/bin). So I'm stuck.
How do I make a script source a file as a user?

source is a builtin not a command, use it with bash -c:
sudo -u $user -H bash -c "source /home/$user/list_of_commands"

Related

Script has random 'Operation Not Permitted' Error

Premise
I couldn't find a tool or script that would rename multiple files (100+) in the manner I needed it to. So I tried to write a Bash Script utilizing the 'mv' command.
Problem
The script does it's job and renames most of the files but then randomly outputs the 'Operation Not Permitted' error while renaming the files.
Error Output
mv: cannot move 'filename.extension' to 'newFilename.extension': Operation not permitted
The Script
a=1
for i in *.<extension>; do
newName=$(printf "%03d <filename>.<extension>" "$a") #03 = Amount of 0 Padding you want to add
sudo mv -i -- "$i" "$newName"
let a=a+1
done
Thank You in advance for any possible help.
It is rarely a good idea to have sudo inside scripts. Instead, remove the sudo from the script and run the script itself with sudo:
sudo myscript.sh
That way, all commands within the script will be run with root privileges and you only need to give the password once when launching the script.
Instead of putting sudo in the script remove it and run the script using sudo.
sudo script.sh
If that still doesn't work make sure your user id is in the sudoers file so you will have the necessary root privileges.

My sh codes don't work, help needed

I'm learning to work with linux but it isn't working out
Script 1, did work until I updated opensuse:
#!/bin/bash
useradd Test
passwd Test123
mkhomedir_helper Test
(It now says that all these commands don't exist)
Script 2, I can only get into my MySql console and he doesn't execute everything:
#!/bin/bash
mysql -u root -ppassword
sleep 3
CREATE USER 'Test'#'localhost' IDENTIFIED BY 'password'
I would really appreciate some help here since I'm new to linux
Run following cmd:
echo $PATH
Output should be list some paths as below
/Usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
If not then run below command:
export PATH="/Usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin"
Now try running above script-1, if it still gives same error, then you are missing some packages, install 'pam' package which contains mkhomedir_helper binaries, so run following command to install pam.
zypper in pam
Script 2, to run mysql query from command line or as a shell script you need to use '-e' option, change the script 2 as below:
#!/bin/bash
mysql -u root -ppassword -e 'CREATE USER "Test"#"localhost" IDENTIFIED BY "password"'

Use source with script that contains sudo command

I have a script that copies files between servers. I am using the lsof command to make sure that the file is not being written to before being moved. The user running the script and the user writing to the file are different, so I need to sudo to the file owner. Here is the relevant line in the sudoers file :
userA ALL=(userB:userB) NOPASSWD: ALL
In the main script (ran as userA), I have tried calling sudo then the subscript containing the lsof command:
sudo su - userB -c 'source ./getOpenFiles.sh'
getOpenFiles.sh has this one line:
#!/bin/bash
lsofResult=$(/usr/sbin/lsof "${sourcePath}")
I have also tried calling the subscript:
source ./getOpenFiles.sh
Then have the first line of the subscript be the sudo:
#!/bin/bash
sudo su - banjobs
lsofResult=$(/usr/sbin/lsof "${sourcePath}")`.
Neither solution is working.
What you actually want is something more like:
lsofResult=$(sudo -u banjobs lsof "${sourcePath}")
Let's go over why the other approaches didn't work one-at-a-time:
Running source under sudo su -c
sudo su - userB -c 'source ./getOpenFiles.sh'
...uses sudo to run su, which runs sh -c 'source ./getOpenFiles.sh'. This doesn't work for several independent reasons:
sh -c 'source ./getOpenFiles.sh' relies on the source keyword being available in /bin/sh, but this is a bash extension.
Even if your /bin/sh is provided by bash, this still defeats the purpose of using source: By starting a new copy of /bin/sh and sourcing your script into that, you're defining the variable in the new shell, not in the original shell that started sudo su.
Running sudo su - banjobs, followed by lsofResult=$(/usr/sbin/lsof "${sourcePath}")
...means that lsofResult=$(...) doesn't run until after sudo su - banjobs exits. If sudo su - banjobs has exited, then the current user isn't banjobs any more, so the sudo command has no effect whatsoever on the lsof.
Demonstrating, in detail, how to test this (for folks who don't have a banoff or userB account on their system):
# place relevant contents in sourceme.bash
# switching from lsof to fuser for this test since OS X lsof does not accept a directory
# as an argument.
cat >sourceme.bash <<'EOF'
lsofResult=$(sudo -u root fuser "${sourcePath}" 2>&1)
EOF
# set sourcePath in the outer shell
sourcePath=$PWD
source sourceme.bash
declare -p lsofResult
...yields, on my system, output akin to the following:
declare -- lsofResult="/Users/chaduffy/tmp: 17165c 17686c 17687c 17688c 17689c 17690c"
...showing that the code in question did in fact work as described.

sudo: command not found

I am trying to execute screen as another user using sudo.
I'm using the command:
echo 'userpassword' | /usr/bin/sudo -u 'myuser' -S '/usr/bin/screen -ls'
Any help found on the internet says that the sudo clears the environment variables (like PATH). So I decided to use the full path to the applications but I'm still getting the command not found error.
Error:
sudo: /usr/bin/screen -ls: command not found
Sudo is installed on the system.
Screen is installed on the system.
For sudo, I have tried the -E and -H flag but it doesn't help.
I tried to set PATH variable using something like this:
... | /usr/bin/sudo -u 'myuser' -S 'env PATH=$PATH; /usr/bin/screen -ls'
Supposedly the $PATH was suppose to expand before the command executes but I was getting other errors...
Can someone provide a command that will let me execute commands as another user and explain what each part of the command does so I can understand it?
Thanks.
Try,
export PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:$PATH
Probably you replaced the path variable while trying to set a new path variable.
Going forward, do 'echo $PATH' before adding a new path variable.
There doesn's seem to be any need to encapsulate command in quotes, without them it even works.
echo 'userpassword' | /usr/bin/sudo -u 'myuser' -S screen -ls

What does this command mean?

While installing QT, I met this command:
sudo -s chmod u+x QtSdk-offline-linux-x86_64-v1.2.1.run
I wonder what -s means here.And it seems similar here:
sudo -s ./QtSdk-offline-linux-x86_64-v1.2.1.run -style cleanlooks
sudo -s runs a shell with root privileges
"The -s (shell) option runs the shell specified by the SHELL
environment variable if it is set or the shell as specified in
passwd(5). If a command is specified, it is passed to the shell for
execution. Otherwise, an interactive shell is executed."
From here.
As mentioned in the comments above, check out the man info:
Type man sudo to your command line.
Find -s in the list of commands for a good explanation.

Resources