How this command find a file in Rpm package - linux

I have given command which will find a particular file named /etc/limits in one of rpm package insatlled but when run on my system getting error not the desired result. Below is the command
find . -name '*.rpm' | while read A; do $RPM -qpl $A | grep etc/limits; \
if [ $? -eq 0 ]; then echo $A; fi; done
/etc/limits
When I run this command getting below error
bash: syntax error near unexpected token `/etc/limits'
Could anybody tell me what is going wrong here?

It's evident that your while loop takes input from find so you don't need /etc/limits after done in your script. Saying:
find . -name '*.rpm' | while read A; do
$RPM -qpl $A | grep /etc/limits;
if [ $? -eq 0 ]; then echo $A; fi;
done
should work. If you wanted to make the while loop read from a file you'd have said:
while read A; do ... done < /path/to/input/file

Related

Searching for a substring in a bash script will not work

I have been writing a bash script to call in my .bashrc file to print the results of whatis for a random command in my /usr/bin folder and wanted to exclude commands that returned "nothing appropriate" in the result and even if I use grep, wc, expr, ==, nothing seems to work. I have pretty much used every example here, and here with no progress. This is what I have so far but failes to do what I want when it finds somthing that contains "nothing appropriate." If anyone could figure out how to get it to work or what a good solution would be in this situation I would be greatfull.
#! /bin/bash
echo "Did you know that:";
while :
do
RESULT=$(whatis $(ls /usr/bin | shuf -n 1))
if [[ $RESULT != *"nothing appropriate"* ]]
then
echo $RESULT
break
fi
done
whatis prints the nothing appropriate message on the standard error stream. This stream is not caught by the $( ). This is the reason of your issue.
This is a way to fix it:
#! /bin/bash
echo "Did you know that:";
while :
do
RESULT=$(whatis $(ls /usr/bin | shuf -n 1) 2>&1 | cat - )
if [[ $RESULT != *"nothing appropriate"* ]]
then
echo $RESULT
break
fi
done
The 2>&1 | cat - addition does the trick

Bash scripting wanting to find a size of a directory and if size is greater than x then do a task

I have put the following together with a couple of other articles but it does not seem to be working. What I am trying to do eventually do is for it to check the directory size and then if the directory has new content above a certain total size it will then let me know.
#!/bin/bash
file=private/videos/tv
minimumsize=2
actualsize=$(du -m "$file" | cut -f 1)
if [ $actualsize -ge $minimumsize ]; then
echo "nothing here to see"
else
echo "time to sync"
fi
this is the output:
./sync.sh: line 5: [: too many arguments
time to sync
I am new to bash scripting so thank you in advance.
The error:
[: too many arguments
seems to indicate that either $actualsize or $minimumsize is expanding to more than one argument.
Change your script as follows:
#!/bin/bash
set -x # Add this line.
file=private/videos/tv
minimumsize=2
actualsize=$(du -m "$file" | cut -f 1)
echo "[$actualsize] [$minimumsize]" # Add this line.
if [ $actualsize -ge $minimumsize ]; then
echo "nothing here to see"
else
echo "time to sync"
fi
The set -x will echo commands before attempting to execute them, something which assists greatly with debugging.
The echo "[$actualsize] [$minimumsize]" will assist in trying to establish whether these variables are badly formatted or not, before the attempted comparison.
If you do that, you'll no doubt find that some arguments will result in a lot of output from the du -m command since it descends into subdirectories and gives you multiple lines of output.
If you want a single line of output for all the subdirectories aggregated, you have to use the -s flag as well:
actualsize=$(du -ms "$file" | cut -f 1)
If instead you don't want any of the subdirectories taken into account, you can take a slightly different approach, limiting the depth to one and tallying up all the sizes:
actualsize=$(find . -maxdepth 1 -type f -print0 | xargs -0 ls -al | awk '{s += $6} END {print int(s/1024/1024)}')

Directory checking in Linux

I am trying to write a script shell that takes two arguments as directory names, and determines if Directory 1 contains Directory 2 or vice versa. And also if there is no relationship between them.
I know the command to check if a directory exists is find -type d, however i was a bit confused as how to check and parse then names. I know i would need if-else loops, just not sure how to check for the conditions?
find won't be needed.
Something similar to this (but not guaranteeing directory name with spaces or some special characters.):
if [ "$dir1" == "$dir2" ]; then
echo "$dir1 == $dir2";
exit;
fi
if grep -E -q "^$dir2" <<< $dir1; then
echo "$dir1 is contained by $dir2."
exit
fi
if grep -E -q "^$dir1" <<< $dir2; then
echo "$dir2 is contained by $dir1.";
fi
However, this does not deal with symbolic links. For example, sym1 -> /usr/local/bin and sym2 -> /usr/local, apparently, sym2 contains sym1.
In addition, this does not deal with strange looking directory names, like /usr/local/./bin, which is the same as /usr/local/bin, or even /usr/local/../bin, which is the same as /usr/bin
--- Update ---
DevSolar metioned that readlink -e can be used to resolve the symbolic link. In my test, it also resolves the strange looking directory names like those with . and ... Thanks to DevSolar.
Do you want this?
if [ -d $1 ];then
a=`find $1 -type d -name $2`
if [ $a ];then
echo "$1 has $2"
else
echo "$1 does NOT has $2"
fi
fi
if [ -d $2 ];then
b=`find $2 -type d -name $1`
if [ $b ];then
echo "$2 has $1"
else
echo "$2 does NOT has $1"
fi
fi
This will do the trick I think,
find -name directory1 |grep directory2
or vice-versa, then use
echo $?
it will give 0 for success and 1 for failure.

Too many arguments in for

In both for statements, I am getting the following error:
./count_files.sh: line 21: [: too many arguments
./count_files.sh: line 16: [: too many arguments.
Can anyone help me ?
#!/bin/bash
files=($(find /usr/src/linux-headers-3.13.0-34/include/ -type f -name '[aeiou][a-z0-9]*.h'))
count=0
headerfiles=($(find /usr/src/linux-headers-3.13.0-34/include/ -type f -name '[_a-zA-Z0-9]*.h' | grep -v "/linux/"))
for file in "${files[#]}"
do
if ! [ grep -Fxq "linux/err.h" $file ];
then
localcount=0
for header in "${headerfiles[#]}"
do
if [ grep -Fxq $header $file ];
then
localcount=$((localcount+1))
if [ $localcount -eq 3 ];
then
count=$(($count+1))
break
fi
fi
done
localcount=0
fi
done
echo $count
One of the problem lines is:
if ! [ grep -Fxq "linux/err.h" $file ];
The semicolon at the end is unnecessary unless the then is on the same line; it is, however, harmless.
It looks as though you want to execute the grep command and check whether it produces any output. However, you've simply provided the test (aka [) command with four string arguments (plus the closing ] for 5 in total), the second of which is not one of the options recognized by test.
You might have meant to use this:
if ! [ -n "$(grep -Fxq "linux/err.h" "$file")" ]
(unless you meant -z instead of -n; the negations are confusing me). But if you're interested in whether grep found anything, you can simply test the exit status of grep:
if grep -Fxq "linux/err.h" "$file"
Hmmm...the -q is 'quiet' mode; so in fact the string test won't work since grep produces no output. You want the direct test of the exit status, possibly preceded by the ! logical not operator.
You shouldn't use square brackets around the grep.
In shell scripts square brackets are not used for grouping, [ is a command in its own right (an alias for test), and it is the [ command that is complaining that you've given it too many arguments.
Just make the call without brackets
if ! grep ....
Change the fors to whiles with reads:
...
echo "${files}" | while read file ; do
...
echo "${headerfiles}" | while read header ; do
...
done
...
done
...

how to compare umask

I am trying to compare the umask of an user. I am getting an error while doing the comparison. The code I am using is
val=`su - user -c "umask" | tail -2 | sed -n "/[0-9]/p"`
if [ $val -eq 744 ]
then
echo "477 found."
fi
When I execute this I am geting an error like:
sh: ^[H: A test command parameter is not valid.
I've tried with = in the compare command, but it is still not working.
Please give any suggestions.
Regards.
val has been initialised as 0.
I am running this as root, so no login is there.
I've also tried giving quotes.
You should quote the variable name in your test expression:
if [ "$val" -eq 744 ]
See here for why.
Your code executes well on my machine, the only solution I can suggest is to use a slightly different syntax, sometimes different bash version complain about one syntax and accept another one:
val=`su - user -c "umask" | tail -2 | sed -n "/[0-9]/p"`
if [[ $val -eq 477 ]] ; then
echo "477 found."
fi
Have a look here for the difference between [ cond ] and [[ cond ]].

Resources