how to get uuid of filesystem given a path? - linux

I am handed a path of a directory ( sometimes path of a file ).
Which utility / shell script will reliably give me the UUID of the filesystem on which is this directory ( or file ) located / stored ?
( by UUID of filesystems I mean the "UUID=..." entry as shown by e.g. blkid )
( this is happnening on a redhat linux )

give this line a try:
sudo blkid -o value $(\df --output=source "$file"|tail -1)|head -1
in above line, $file is the variable to save the file/dir. You may want to check if the file/dir exists, before call the line.
And this line needs root permission (sudo)
\df is just for avoiding to use alias if you had one, for example with -T option, it conflicts with --output
Some test :
kent$ file="/home/kent/.vimrc"
kent$ sudo blkid -o value $(\df --output=source "$file"|tail -1)|head -1
9da1040a-4a24-4a00-9c62-bad8cc3c028d
kent$ file="/etc"
kent$ sudo blkid -o value $(\df --output=source "$file"|tail -1)|head -1
2860a386-af71-4a28-86d7-00ccf5d12b4d

Find the device of the mount point of the path,
DEVICE=$(df /path/to/some_file_or_directory | grep "$MOUNTPOINT\$"| cut -f1 -d" ")
and get the UUID of the device:
sudo blkid $DEVICE

Simply, you can type like this,
pchero#mywork:~$ ls -l /dev/disk/by-uuid/
total 0
lrwxrwxrwx 1 root root 10 Jan 23 09:03 0267689b-b929-4f30-b8a4-08c742f0746f -> ../../sda2
lrwxrwxrwx 1 root root 10 Jan 23 09:03 2d682ea1-dab0-49ba-a77a-9335ccd47e58 -> ../../sda3
lrwxrwxrwx 1 root root 10 Jan 23 09:03 64e733e9-2e6a-4d3e-aabe-d0d26fbfc991 -> ../../sda1
lrwxrwxrwx 1 root root 10 Jan 23 09:03 a99fb356-4e01-4a1c-af41-001b0fd8a844 -> ../../sdb1
lrwxrwxrwx 1 root root 10 Jan 23 09:03 f2f7618e-76c5-4e9a-9657-e002d9a66ccf -> ../../sda4

Related

Get clean list of file sizes and names using SFTP in unix

I want to fetch list of files from a server using SFTP one by one only if their size is less than 1 GB.
I am running the following command :
$sftp -oIdentityFile=/home/user/.ssh/id_rsa -oPort=22 user#hostname >list.txt <<EOF
cd upload/Example
ls -l iurygify*.zip
EOF
This results in:
$cat list.txt
sftp> cd upload/Example
sftp> ls -l iurygify*.zip
-rwxrwx--- 0 300096661 300026669 0 Mar 11 16:38 iurygify1.zip
-rwxrwx--- 0 300096661 300026669 0 Mar 11 16:38 iurygify2.zip
I could then use awk to calculate get the size and filename which I can save into logs for reference and then download only those files which meet the 1 GB criteria.
Is there any simpler approach to accomplish getting this file list and size? I want to avoid the junk entires of the prompt and commands in the list.txt and do not want to do this via expect command.
We are using SSH key authentication
You could place your sftp commands in a batch file and filter the output - no need for expect.
echo 'ls -l' > t
sftp -b t -oIdentityFile=/home/user/.ssh/id_rsa -oPort=22 user#hostname | grep -v 'sftp>' >list.txt
Or take it a step further and filter out the "right size" in the same step:
sftp -b t -oIdentityFile=/home/user/.ssh/id_rsa -oPort=22 user#hostname | awk '$1!~/sftp>/&&$5<1000000000' >list.txt
Maybe using lftp instead of sftp ?
$ lftp sftp://xxx > list.txt <<EOF
> open
> ls -l
> EOF
$ cat list.txt
drwxr-xr-x 10 ludo users 4096 May 24 2019 .
drwxr-xr-x 8 root root 4096 Dec 20 2018 ..
-rw------- 1 ludo users 36653 Mar 31 19:28 .bash_history
-rw-r--r-- 1 ludo users 220 Mar 21 2014 .bash_logout
-rw-r--r-- 1 ludo users 362 Aug 16 2018 .bash_profile
...

Linux script to create new directory with name as datestamp

The current script is functional, but the output is slightly off. This is what I have so far.
echo "Which client are we backing up today? Choose one below."
ls -la /usr/local/nagios/etc/objects/Clients | awk '{print $9}'
read varname
cd /usr/local/nagios/etc/objects/Clients/$varname
while true; do
read -p "Backup files located in nagtech/backup to current client directory? (y/n) " yn
case $yn in
[Yy]* ) cp -r /home/nagtech/backup $varname > mkdir$(date +m%-%d-%y); break;;
[Nn]* ) exit;;
* ) echo "Please anwser yes or no.";;
esac
done
My intention is to have a new DIRECTORY created and NAMED with the current date stamp if input is y. However its not quite there. Below is sample output when "y" is entered and $varname is set to "HELP".
drwxr-xr-x 4 root root 4096 Aug 24 17:45 .
drwxr-xr-x 16 root root 4096 Aug 22 18:36 ..
drwxr-xr-x 2 root root 4096 Aug 22 18:38 08.22.18
-rw-r--r-- 1 root root 0 Aug 24 17:45 mkdirm%d-18
drwxr-xr-x 3 root root 4096 Aug 24 17:45 HELP
The destination of cp is the second argument to the command. You're using the date as the name of a file to redirect the output, but cp doesn't produce any output.
You need to execute the mkdir command to create the directory, and then use that as the destination of the cp command.
[Yy]* ) newdir=$(date +m%-%d-%y)
mkdir "$newdir"
cp -r /home/nagtech/backup "$newdir"
;;

Formatting text and adding text-part between specific pattern

On GNU/Linux, I've following output by running ls command:
$ ls -l /dev/disk/by-label/
total 0
lrwxrwxrwx 1 root root 10 Mar 4 18:21 Documents+Edu -> ../../sda4
lrwxrwxrwx 1 root root 10 Mar 4 18:17 Ext4 -> ../../sda3
lrwxrwxrwx 1 root root 10 Mar 4 18:21 Game+Movie -> ../../sda6
lrwxrwxrwx 1 root root 10 Mar 4 18:42 OS -> ../../sda7
lrwxrwxrwx 1 root root 10 Mar 4 18:20 Software+Video -> ../../sda5
And I want the following output:
sudo mount /dev/sda4 /media/$USER/Documents+Edu
sudo mount /dev/sda3 /media/$USER/Ext4
sudo mount /dev/sda6 /media/$USER/Game+Movie
sudo mount /dev/sda7 /media/$USER/OS
sudo mount /dev/sda5 /media/$USER/Software+Video
In other words:-
Adding text sudo mount /dev/ before every /sdax and /media/$USER/ before labels like: Documents+Edu etc.
Formatting as needed.
How can I achieve desired output on Linux by using commands like: grep, cut, awk, sed, etc.?
Another option could be to avoid ls altogether iterating through the files with readlink:
$ cat ../nols.sh
cd /dev/disk/by-label
for f in *
do
v=$(basename $(readlink $f))
echo "sudo mount /dev/$v /media/\$USER/$f"
done
$ sh ../nols.sh
sudo mount /dev/sda4 /media/$USER/Documents+Edu
sudo mount /dev/sda3 /media/$USER/Ext4
sudo mount /dev/sda6 /media/$USER/Game+Movie
sudo mount /dev/sda7 /media/$USER/OS
sudo mount /dev/sda5 /media/$USER/Software+Video
Since you don't need anything apart from the names and its symbolic links, it might me best to just do ls -1 (one instead of L) ot just get the last column. Then, pipe to this awk:
awk -F"->|/" '{printf "sudo mount /dev/%s /media/$USER/%s\n", $NF, $1}'
It slices the text in either -> or / separators. Based on that, it gets the last one and the first one and populates the string accordingly.
Test
$ ls -1 /dev/disk/by-label/ | awk -F"->|/" '{printf "sudo mount /dev/%s /media/$USER/%s\n", $NF, $1}'
sudo mount /dev/sda4 /media/$USER/Documents+Edu
sudo mount /dev/sda3 /media/$USER/Ext4
sudo mount /dev/sda6 /media/$USER/Game+Movie
sudo mount /dev/sda7 /media/$USER/OS
sudo mount /dev/sda5 /media/$USER/Software+Video
# -- Prepare ---
Folder='/dev/disk/by-label/'
HeaderLen=$(ls -ld . | wc -c )
# -- execute ---
ls -l "${Folder}" | sed "1d;s#.\{${HeaderLen}\}\(.*\) -> .*\(/[^/]*\)#sudo mount /dev\2 /media/\$USER/\1#;t;d"
estimate the first partof ls that is not used (and will be removed)
list the folder pipe to a sed
remove 1st line (total info)
remove first part and take 2 group of text separate by ->, rewrtie it in new format
if substitution occur, go to end of script (print)
if no, remove the line (and cycle without print). This remove file not linked in your format

Using sed within "while read" expression

I am pretty stuck with that script.
#!/bin/bash
STARTDIR=$1
MNTDIR=/tmp/test/mnt
find $STARTDIR -type l |
while read file;
do
echo Found symlink file: $file
DIR=`sed 's|/\w*$||'`
MKDIR=${MNTDIR}${DIR}
mkdir -p $MKDIR
cp -L $file $MKDIR
done
I passing some directory to $1 parameter, this directory have three symbolic links. In while statement echoed only first match, after using sed I lost all other matches.
Look for output below:
[artyom#LBOX tmp]$ ls -lh /tmp/imp/
total 16K
lrwxrwxrwx 1 artyom adm 19 Aug 8 10:33 ok1 -> /tmp/imp/sym3/file1
lrwxrwxrwx 1 artyom adm 19 Aug 8 09:19 ok2 -> /tmp/imp/sym2/file2
lrwxrwxrwx 1 artyom adm 19 Aug 8 10:32 ok3 -> /tmp/imp/sym3/file3
[artyom#LBOX tmp]$ ./copy.sh /tmp/imp/
Found symlink file: /tmp/imp/ok1
[artyom#LBOX tmp]$
Can somebody help with that issue?
Thanks
You forgot to feed something to sed. Without explicit input, it reads nothing in this construction. I wouldn't use this approach anyway, but just use something like:
DIR=`dirname "$file"`

How to check syslog in Bash on Linux?

In C we log this way:
syslog( LOG_INFO, "proxying %s", url );
In Linux how can we check the log?
How about less /var/log/syslog?
On Fedora 19, it looks like the answer is /var/log/messages. Although check /etc/rsyslog.conf if it has been changed.
By default it's logged into system log at /var/log/syslog, so it can be read by:
tail -f /var/log/syslog
If the file doesn't exist, check /etc/syslog.conf to see configuration file for syslogd.
Note that the configuration file could be different, so check the running process if it's using different file:
# ps wuax | grep syslog
root /sbin/syslogd -f /etc/syslog-knoppix.conf
Note: In some distributions (such as Knoppix) all logged messages could be sent into different terminal (e.g. /dev/tty12), so to access e.g. tty12 try pressing Control+Alt+F12.
You can also use lsof tool to find out which log file the syslogd process is using, e.g.
sudo lsof -p $(pgrep syslog) | grep log$
To send the test message to syslogd in shell, you may try:
echo test | logger
For troubleshooting use a trace tool (strace on Linux, dtruss on Unix), e.g.:
sudo strace -fp $(cat /var/run/syslogd.pid)
A very cool util is journalctl.
For example, to show syslog to console: journalctl -t <syslog-ident>, where <syslog-ident> is identity you gave to function openlog to initialize syslog.
tail -f /var/log/syslog | grep process_name
where process_name is the name of the process we are interested in
If you like Vim, it has built-in syntax highlighting for the syslog file, e.g. it will highlight error messages in red.
vi +'syntax on' /var/log/syslog
On some Linux systems (e.g. Debian and Ubuntu) syslog is rotated daily and you have multiple log files where two newest files are uncompressed while older ones are compressed:
$ ls -l /var/log/syslog*
-rw-r----- 1 root adm 888238 Aug 25 12:02 /var/log/syslog
-rw-r----- 1 root adm 1438588 Aug 25 00:05 /var/log/syslog.1
-rw-r----- 1 root adm 95161 Aug 24 00:07 /var/log/syslog.2.gz
-rw-r----- 1 root adm 103829 Aug 23 00:08 /var/log/syslog.3.gz
-rw-r----- 1 root adm 82679 Aug 22 00:06 /var/log/syslog.4.gz
-rw-r----- 1 root adm 270313 Aug 21 00:10 /var/log/syslog.5.gz
-rw-r----- 1 root adm 110724 Aug 20 00:09 /var/log/syslog.6.gz
-rw-r----- 1 root adm 178880 Aug 19 00:08 /var/log/syslog.7.gz
To search all the syslog files you can use the following commands:
$ sudo zcat -f `ls -tr /var/log/syslog*` | grep -i error | less
where zcat first decompresses and prints all syslog files (oldest first), grep makes a search and less is paging the results of the search.
To do the same but with the lines prefixed with the name of the syslog file you can use zgrep:
$ sudo zgrep -i error `ls -tr /var/log/syslog*` | less
$ zgrep -V | grep zgrep
zgrep (gzip) 1.6
In both cases sudo is required if syslog files are not readable by ordinary users.

Resources