How do I create a flag using getopts to run mount command in linux? - linux

I need help with my script.
My script is to find if a mount exists. Though I want it run only if I pass a flag using getopts. How can I do that?
FS_TO_CHECK="/dev"
if cat /proc/mounts | grep $FS_TO_CHECK > /dev/null; then
# Filesystem is mounted
else
# Filesystem is not mounted
fi

The simplest example of passing a command line argument:
$ ./MyScript.sh some_parameter
MyScript.sh:
#!/bin/bash
echo $1
Here's a simple tutorial on getopts.

Related

Determine command line arguments a program uses to launch another one?

Motivation: When I run grub-mkrescue, it internally launches xorriso to write an iso file. I want to see what command line arguments xorriso is being passed. I know I could check the sources of grub-mkrescue, but I'm interested in a generic solution now. I tried with strace but the output didn't tell.
strace grub-mkrescue -o foo.iso iso/
Is there a way to do this?
A process will fork before running execve, so it will not show up in the strace of the parent.
Use strace -f to also follow children.
You can replace xorriso with a more verbose one:
which xorisso
cd $(dirname $(which ps))
mv xorisso xorisso.org
test -f xorisso | echo "mv failed, stop here"
cat <<'#' > xorisso
echo "$0 $#" > /tmp/xorisso_call.tmp
"$0.org" "$#"
#
chmod +x xorisso

Use bash in conky.config

You can use bash code, and call bash scripts, in conky.text. Is there any way to use it in conky.config?
The reason I want this is to have window specifications depending on whether I have an external monitor connected or not.
So I want logic similar to this:
if xrandr -q | grep -oP 'HDMI2\sconnected' > /dev/null ; then
x=-900
else
x=0
fi
gap_x=$x
I personally do not encourage the following solution, but if all else fails, this will at least work very well.
Make a copy of your .conkyrc file, let's call it .conkyrc_dual, and make the bash file below:
#!/bin/bash
pkill conky
if xrandr -q | grep -oP 'HDMI2\sconnected' > /dev/null ; then
conky -c ~/.conkyrc_dual
notify-send 'Conky' 'Dual monitors'
else
conky
notify-send 'Conky' 'Single monitor'
fi
Now run this file when you want to start conky.
You could also have a bash script use sed to edit the gap_x variable in your .conkyrc file as needed before starting conky. That way, you'd only need a single config file. Keep a backup of .conkyrc, of course, just in case something goes terribly awry.

What kind of command is "sudo", "su", or "torify"

I know what they do. I was just wondering what kind of command are they. How can you make one using shell scripting.
For example, command like:
ignoreError ls /Home/
ignoreError mkdir /Home/
ignoreError cat
ignoreError randomcommand
Hope you get the idea
The way to do it in a shell script is with the "$#" construct.
"$#" expands to a quoted list of all of the arguments you passed to your shell script. $1 would be the command you want your shell script to run, and $2 $3 etc are the arguments to that command.
The only example I have is from cygwin. Cygwin does not have sudo, but I have this script that emulates it:
#!/usr/bin/bash
cygstart --action=runas "$#"
So when I run a command like
$ sudo ls -l
my sudo script does whatever it needs to do (cygstart --action=runas) and calls the ls command with the -l argument.
Try this script:
#!/bin/sh
"$#"
Call it, for example, run, make it runnable chmod u+x run, and try it:
$ run ls -l #or ./run ls -l
...
output of ls
...
The idea is that the script takes the parameters specified on the command line and use them as a (sub)command... Modify the script this way:
#!/bin/sh
echo "Trying to run $*"
"$#"
and you will see.

pseudo-terminal error will not be allocated because stdin is not a terminal - sudo

There are other threads with this same topic but my issue is unique. I am running a bash script that has a function that sshes to a remote server and runs a sudo command on the remote server. I'm using the ssh -t option to avoid the requiretty issue. The offending line of code works fine as long as it's NOT being called from within the while loop. The while loop basically reads from a csv file on the local server and calls the checkAuthType function:
while read inputline
do
ARRAY=(`echo $inputline | tr ',' ' '`)
HOSTNAME=${ARRAY[0]}
OS_TYPE=${ARRAY[1]}
checkAuthType $HOSTNAME $OS_TYPE
<more irrelevant code>
done < configfile.csv
This is the function that sits at the top of the script (outside of any while loops):
function checkAuthType()
{
if [ $2 == linux ]; then
LINE=`ssh -t $1 'sudo grep "PasswordAuthentication" /etc/ssh/sshd_config | grep -v "yes\|Yes\|#"'`
fi
if [ $2 == unix ]; then
LINE=`ssh -n $1 'grep "PasswordAuthentication" /usr/local/etc/sshd_config | grep -v "yes\|Yes\|#"'`
fi
<more irrelevant code>
}
So, the offending line is the line that has the sudo command within the function. I can change the command to something simple like "sudo ls -l" and I will still get the "stdin is not a terminal" error. I've also tried "ssh -t -t" but to no avail. But if I call the checkAuthType function from outside of the while loop, it works fine. What is it about the while loop that changes the terminal and how do I fix it? Thank you one thousand times in advance.
Another option to try to get around the problem would be to redirect the file to a different file descriptor and force read to read from it instead.
while read inputline <&3
do
ARRAY=(`echo $inputline | tr ',' ' '`)
HOSTNAME=${ARRAY[0]}
OS_TYPE=${ARRAY[1]}
checkAuthType $HOSTNAME $OS_TYPE
<more irrelevant code>
done 3< configfile.csv
I am guessing you are testing with linux. You should try add the -n flag to your (linux) ssh command to avoid having ssh read from stdin - as it normally reads from stdin the while loop is feeding it your csv.
UPDATE
You should (usually) use the -n flag when scripting with SSH, and the flag is typically needed for 'expected behavior' when using a while read-loop. It does not seem to be the main issue here, though.
There are probably other solutions to this, but you could try adding another -t flag to force pseudo-tty allocation when stdin is not a terminal:
ssh -n -t -t
BroSlow's approach with a different file descriptor seems to work! Since the read command reads from fd 3 and not stdin,
ssh and hence sudo still have or get a tty/pty as stdin.
# simple test case
while read line <&3; do
sudo -k
echo "$line"
ssh -t localhost 'sudo ls -ld /'
done 3<&- 3< <(echo 1; sleep 3; echo 2; sleep 3)

Check if directory mounted with bash

I am using
mount -o bind /some/directory/here /foo/bar
I want to check /foo/bar though with a bash script, and see if its been mounted? If not, then call the above mount command, else do something else. How can I do this?
CentOS is the operating system.
You didn't bother to mention an O/S.
Ubuntu Linux 11.10 (and probably most up-to-date flavors of Linux) have the mountpoint command.
Here's an example on one of my servers:
$ mountpoint /oracle
/oracle is a mountpoint
$ mountpoint /bin
/bin is not a mountpoint
Actually, in your case, you should be able to use the -q option, like this:
mountpoint -q /foo/bar || mount -o bind /some/directory/here /foo/bar
Running the mount command without arguments will tell you the current mounts. From a shell script, you can check for the mount point with grep and an if-statement:
if mount | grep /mnt/md0 > /dev/null; then
echo "yay"
else
echo "nay"
fi
In my example, the if-statement is checking the exit code of grep, which indicates if there was a match. Since I don't want the output to be displayed when there is a match, I'm redirecting it to /dev/null.
The manual of mountpoint says that it:
checks whether the given directory or file is mentioned in the /proc/self/mountinfo file.
The manual of mount says that:
The listing mode is maintained for backward compatibility only. For
more robust and customizable output use findmnt(8), especially in your
scripts.
So the correct command to use is findmnt, which is itself part of the util-linux package and, according to the manual:
is able to search in /etc/fstab, /etc/mtab or /proc/self/mountinfo
So it actually searches more things than mountpoint. It also provides the convenient option:
-M, --mountpoint path
Explicitly define the mountpoint file or directory. See also --target.
In summary, to check whether a directory is mounted with bash, you can use:
if [[ $(findmnt -M "$FOLDER") ]]; then
echo "Mounted"
else
echo "Not mounted"
fi
Example:
mkdir -p /tmp/foo/{a,b}
cd /tmp/foo
sudo mount -o bind a b
touch a/file
ls b/ # should show file
rm -f b/file
ls a/ # should show nothing
[[ $(findmnt -M b) ]] && echo "Mounted"
sudo umount b
[[ $(findmnt -M b) ]] || echo "Unmounted"
My solution:
is_mount() {
path=$(readlink -f $1)
grep -q "$path" /proc/mounts
}
Example:
is_mount /path/to/var/run/mydir/ || mount --bind /var/run/mydir/ /path/to/var/run/mydir/
For Mark J. Bobak's answer, mountpoint not work if mount with bind option in different filesystem.
For Christopher Neylan's answer, it's not need to redirect grep's output to /dev/null, just use grep -q instead.
The most important, canonicalize the path by using readlink -f $mypath:
If you check path such as /path/to/dir/ end with backslash, the path in /proc/mounts or mount output is /path/to/dir
In most linux release, /var/run/ is the symlink of /run/, so if you mount bind for /var/run/mypath and check if it mounted, it will display as /run/mypath in /proc/mounts.
I like the answers that use /proc/mounts, but I don't like doing a simple grep. That can give you false positives. What you really want to know is "do any of the rows have this exact string for field number 2". So, ask that question. (in this case I'm checking /opt)
awk -v status=1 '$2 == "/opt" {status=0} END {exit status}' /proc/mounts
# and you can use it in and if like so:
if awk -v status=1 '$2 == "/opt" {status=0} END {exit status}' /proc/mounts; then
echo "yes"
else
echo "no"
fi
The answers here are too complicated just check if the mount exists using:
cat /proc/mounts | tail -n 1
This only outputs the last mounted folder, if you want to see all of them just remove the tail command.
Another clean solution is like that:
$ mount | grep /dev/sdb1 > /dev/null && echo mounted || echo unmounted
For sure, 'echo something' can be substituted by whatever you need to do for each case.
In my .bashrc, I made the following alias:
alias disk-list="sudo fdisk -l"

Resources