How do I sudo if in Bash? - bash

I need to check for a directory in the home directory of another user. Normally I would sudo but that forks another process and I also lose my environment.
For example, I have:
if [[ -d "/home/otheruser/svn" ]];
then
echo "SVN exists"
else
echo "SVN does not exist"
fi
I need the the test condition to run with root permissions.

if sudo test -d "/home/otheruser/svn"; then

You need to run it under a subshell. Example:
if sudo bash -c '[[ -d "/home/otheruser/svn" ]]'
then
echo "SVN exists"
else
echo "SVN does not exist"
fi

Related

How to change name of file if already present on remote machine?

I want to change the name of a file if it is already present on a remote server via SSH.
I tried this from here (SuperUser)
bash
ssh user#localhost -p 2222 'test -f /absolute/path/to/file' && echo 'YES' || echo 'NO'
This works well with a prompt, echoes YES when the file exists and NO when it doesn't. But I want this to be launched from a crontab, then it must be in a script.
Let's assume the file is called data.csv, a condition is set in a loop such as if there already is a data.csv file on the server, the file will be renamed data_1.csv and then data_2.csv, ... until the name is unique.
The renaming part works, but the detection part doesn't :
while [[ $fileIsPresent!='false' ]]
do
((appended+=1))
newFileName=${fileName}_${appended}.csv
remoteFilePathname=${remoteFolder}${newFileName}
ssh pi#localhost -p 2222 'test -f $remoteFilePathname' && fileIsPresent='true' || fileIsPresent='false'
done
always returns fileIsPresent='true' for any data_X.csv. All the paths are absolute.
Do you have any idea to help me?
This works:
$ cat replace.sh
#!/usr/bin/env bash
if [[ "$1" == "" ]]
then
echo "No filename passed."
exit
fi
if [[ ! -e "$1" ]]
then
echo "no such file"
exit
fi
base=${1%%.*} # get basename
ext=${1#*.} # get extension
for i in $(seq 1 100)
do
new="${base}_${i}.${ext}"
if [[ -e "$new" ]]
then
continue
fi
mv $1 $new
exit
done
$ ./replace.sh sample.csv
no such file
$ touch sample.csv
$ ./replace.sh sample.csv
$ ls
replace.sh
sample_1.csv
$ touch sample.csv
$ ./replace.sh sample.csv
$ ls
replace.sh
sample_1.csv
sample_2.csv
However, personally I'd prefer to use a timestamp instead of a number. Note that this sample will run out of names after 100. Timestamps won't. Something like $(date +%Y%m%d_%H%M%S).
As you asked for ideas to help you, I thought it worth mentioning that you probably don't want to start up to 100 ssh processes each one logging into the remote machine, so you might do better with a construct like this that only establishes a single ssh session that runs till complete:
ssh USER#REMOTE <<'EOF'
for ((i=0;i<10;i++)) ; do
echo $i
done
EOF
Alternatively, you can create and test a bash script locally and then run it remotely like this:
ssh USER#REMOTE 'bash -s' < LocallyTestedScript.bash

Continuing a BASH script after error

This script works well in finding what I need, but there are occassions where a 404 error just kills everything.
#!/bin/sh
set +e
exec 7<foo.txt
exec 8<bar.tmp
echo "Retrieving data"
while read line1 <&7 && read line2 <&8
do
echo "beginning... retrieving files from d list"
echo "this WILL take a while"
echo $line1
echo $line2
wget -e robots=off -t1 -r -p -Q20k --wait=30 --random-wait --limit-rate=200k -np -U "$line1" http://$line2/page.html
cp /home/user/testing/*.html /home/user/production
echo "done"
done
exec 7<&-
exec 8<&-
I want to continue the script because even though this site, known as $line2 has a 404, the others don't.
I have done the "set +e", and even ran the script with "|| true", all stopping after the error. Because of the 404, there are no files to copy - and then it fails to go onto the next site.
Any suggestions?
What I found works is this:
if [ ! -d "/home/user/production" ]; then
continue #continue the loop.
fi

SSH hot to check remote directory exist

Idea is to check remote folder. Is it exist or no?
I try this
ssh -p 22 -tt user#server.com 'bash -d /home/test22
and it works fine
/home/test22: /home/test22: is a directory
Connection to server.com closed.
But when I try to use it with "IF" - it is wrong...always said "That directory exists"
#!/bin/bash
if [ "ssh -p 22 -tt user#server.com 'bash -d /home/test22'" ]; then
echo "That directory exists"
else
echo "That directory doesn't exists"
fi
Can you show correct example?
Thank you!
The command to use is not bash but test or its alias [:
if ssh -p 22 -tt user#server.com 'test -d /home/test22'; then
echo "That directory exists"
else
echo "That directory doesn't exists"
fi
The other important thing is that [] is not part of the if syntax. if is always followed by a command and if evaluates its exit status. So no need to surround your ssh command with [].
-d dir are actually the arguments of command test or [.
test -d dir
[ -d dir ]
are identical, the latter form requires a closing ] argument.

Terminating a script execute with user1 without loop

This is an example of My script. How do i terminate it after it execute. it looping.
#!/bin/bash
#Checks root permission
if [ $(id -u) != "0" ]; then
echo "You must be the superuser to run this script" >&2
su -c "$0 $#"
fi
echo "welcome to script"
cd /var/app
cp index.html index10.html
su john -c 'command1 && command2'
if [ $? -eq 0 ];then
cp index10.html index.html
echo "script exit"
else
echo "error"
fi
exit 1
I believe the when the script executes with user john. the su -c "$0 $#" runs it with root. and when the su command is done.. script continues. Is there any way i restrict script without executing and terminate with echo "scriptexit". I mean without removing the su -c "$0 $#" ? I know if script executed as root user then it will fine.
Put an exit after the first su command (inside the if block).

Checking status of program

This always works if I just type:if [ ! "$(pgrep vlc)" ]; then echo not running; else echo running; fi in the command prompt, but as soon as I make it a script, give it chmod +x and run it I always get "running" as the output. Can someone give me a lead?
#!/bin/bash
export DISPLAY=:0
if [ ! "$(pgrep vlc)" ]; then echo not running; else echo running; fi
If the name of your script contains 'vlc', pgrep founds that script running and condition in if is false, even though real VLC is not running.
You could insert
echo "$(pgrep vlc)"
before the if stament
You can be more selective with your pgrep command. It's not necessary to use command substitution and brackets.
#!/bin/bash
export DISPLAY=:0
if ! pgrep -f "/path/to/vlc " >/dev/null; then echo not running; else echo running; fi
another option to avoid mixup with your own script is to use ps's '-C' flag
(I dont know how portable it is though)
if ps -C vlc > /dev/null ; then echo running; else echo not runing; fi

Resources