How can use invert grep after pipe? - bash

I want to list directory disk usage in a fileserver.
I also want to ignore the error messages. Here is my command:
du -sh * | grep -v "Permission denied" | sort -n
The result still contains the permission denied lines:
du: cannot access './myFile1/': Permission denied
du: cannot access './myFile2/': Permission denied
du: cannot access './myFile3/': Permission denied
What am I doing wrong?

This is because the "Permission denied" is sent through standard error, not through standard output.
If you don't want this information, just silence it by redirecting stderr to /dev/null:
du -sh * 2>/dev/null | sort -n
This happens with all these error messages:
$ touch a
$ ls a asfasd
ls: cannot access asfasd: No such file or directory
a
$ ls a asfasd | grep cannot
ls: cannot access asfasd: No such file or directory
$ ls a asfasd 2>/dev/null
a

Related

Bash: Using asterisk in any bash command in home directory exits with error "Unrecognized options --list-sessions"

Title.
This same/similar error seems to occur with any command in bash if I:
Am in my home directory, i.e. after cd ~. It doesnt occur in other places.
Have an asterisk/wildcard in the command matching all of the files+dirs. It doesnt happen without the asterisk as far as I can tell.
Examples:
me#mypc:~$ ls *
ls: unrecognized option '--list-sessions'
Try 'ls --help' for more information.
me#mypc:~$ ls
...
Desktop
Downloads
...
(prints all directories)
me#mypc:~$ ls ./*
(prints all subdirectory subdirectories)
me#mypc:~$ ls .*
...
.vscode:
argv.json extensions
.wine:
dosdevices drive_c system.reg userdef.reg user.reg
...
(prints all subdirectories with their contents)
me#mypc:~$ du -sch *
du: unrecognized option '--list-sessions'
Try 'du --help' for more information.
me#mypc:~$ du -sch .*
du: cannot read directory './.dbus': Permission denied
du: cannot read directory './.pgadmin': Permission denied
66G .
du: cannot read directory '../postgres/.gnupg': Permission denied
64K ..
66G total
me#mypc:~$ grep "\-\-list-sessions" *
grep: unrecognized option '--list-sessions'
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
And so on.
The list-sessions flag seems reminiscent of this tmux command:
me#mypc:~$ tmux list-sessions
error connecting to /tmp/tmux-1000/default (No such file or directory)
me#mypc:~$ whereis tmux
tmux: /usr/bin/tmux /usr/share/man/man1/tmux.1.gz
The list-sessions error in other commands persists with and without running tmux server.
Thanks for your help!
I'm guessing you have a file in your home directory named --list-sessions and the *, when expanded, is causing your command (eg, ls, du) to treat the file name as an option:
Consider ...
$ mkdir /tmp/ttt
$ cd /tmp/ttt
$ touch -- '--list-sessions'
$ ls -a
--list-sessions ./ ../
$ ls *
dir: unknown option -- list-sessions
Try 'dir --help' for more information.
$ ls -- * # disable further command line option processing
--list-sessions
$ du -k *
du: unknown option -- list-sessions
Try 'du --help' for more information.
$ du -k -- * # disable further command line option processing
0 --list-sessions
NOTE: The -- used in the above commands disables further command line option processing, eg, What does double dash mean?

cannot access file: Input/output error d????????? ? ??

I'm having the following problem:
I can't remove a specific file
$ ls -l
ls: cannot access fisier: Input/output error
total 0
d????????? ? ? ? ? ? fisier
$ rm -rf fisier
rm: cannot remove ‘fisier’: Permission denied
$ sudo rm -rf fisier
[sudo] password for myusername:
rm: cannot remove ‘fisier’: Is a directory

SFTP: return number of files in remote directory?

I sent a batch of files to a remote server via SFTP. If it were a local directory I could do something like this ls -l | wc -l to get the total number of files. However, with SFTP, I get an error Can't ls: "/|" not found.
echo ls -l | sftp server | grep -v '^sftp' | wc -l
If you want to count the files in a directory the directory path should be put after the ls -l command like
echo ls -l /my/directory/ | sftp server | grep -v '^sftp' | wc -l
Use a batch file to run commands remotely and get the data back to work with in bash:
Make your batch file called mybatch.txt with these sftp commands:
cd your_directory/your_sub_directory
ls -l
Save it out and give it 777 permissions.
chmod 777 mybatch.txt
Then run it like this:
sftp your_username#your_server.com < mybatch.txt
It will prompt you for the password, enter it.
Then you get the output dumped to bash terminal. So you can pipe that to wc -l like this:
sftp your_user#your_server.com < mybatch.txt | wc -l
Connecting to your_server.com...
your_user#your_server.com's password:
8842
The 8842 is the number of lines returned by ls -l in that directory.
Instead of piping it to wc, you could dump it to a file for parsing to determine how many files/folders.
I would use sftp batch file.
Create a file called batchfile and enter "ls -l" in it.
Then run
sftp -b batchfile user#sftpHost | wc -l
The easiest way I have found is to use the lftp client which supports a shell-like syntax to transfer the output of remote ftp commands to local processes.
For example using the pipe character:
lftp -c 'connect sftp://user_name:password#host_name/directory; ls -l | wc -l'
This will make lftp spawn a local wc -l and give it the output of the remote ls -l ftp command on its stdin.
Shell redirection syntax is also supported and will write directly to local files:
lftp -c 'connect sftp://user_name:password#host_name/directory; ls -l >list.txt'
Thus a file named list.txt containing the remote file listing will be created in the current folder on the local machine. Use >> to append instead.
Works perfectly for me.

Searching Linux Files for a string (i.e.root credentials)

As a part of our audit policy. I need to search all files on a linux machine for any file that contains the root credentials.
This command will be run by a non-root account, thus, the result will include many "Permission denied" statements.
Any suggestion of the proper syntax to search all files ans filter the result to show useful links only !
I tried:
grep - "root" / | grep "password"
However, as this command is run using non root accounts, the big part of the result is "permission denied"
Thanks
The permission errors are outputed to stderr, so you could simply redirect that to /dev/null/. E.g.:
grep -R "root" . 2> /dev/null
You would go:
grep -lir "root" /
The -l switch outputs only the names of files in which the text occurs (instead of each line containing the text), the -i switch ignores the case, and the -r descends into subdirectories.
EDIT 1:
As running it as not root will be fine, as long as you're not trying to read other users' files.
EDIT 2:
To have only useful links, go with:
grep -lir -v "Permission denied" "root" /
The -v switch is for inverting the sense of matching, to select non-matching lines.
However, as this command is run using non root accounts, the big part
of the result is "permission denied"
Use sudo to run this recursive grep:
cd /home
sudo grep -ir 'root' *
You can suppress the warnings with a redirection to /dev/null.
This solution uses find to walk the whole (accessible) filesystem :
find / -readable -exec grep -H root '{}' \; 2>/dev/null | grep password

Redirecting a bash error

I am writing a bash script, which has a problem:
path=$(pwd)
data=$(ls -al $path) > /dev/null 2>/dev/null
The problem occurs if $path is a "locked" directory (no permission for user x), call it "BadDir". In that case, the program outputs:
ls: cannot access /home/user/.../BadDir/..: Permission denied
All I want is to hide this output.
I know there is redirection to /dev/null but I don't know how to use it in this particular case.
you can redirect all error message to another with using EXEC
for test, first create folder
mkdir /tmp/t/
sudo chown root /tmp/t/
sudo chgrp root /tmp/t/
sudo chmod 400 /tmp/t/
e.g:
ls -al /tmp/t/
output:
ls: cannot open directory /tmp/t/: Permission denied
and using EXEC first of file:
exec 2>/dev/null
ls -al /tmp/t/
with exec you can control and redirect all error message or another output

Resources