Linux Tricks - Old tricks to make place for new ones
Some stuff that I encounter that everyone should know - new post
Becuase I have so many tricks and it never stops....(new post for new tricks)
12.10.2022 - 18:43 - Wednesday
This problem came to me when examining logs. I needed to know when a log stops writing.
I wanted to do it in one command, without using complicated scripts or some thid party tool. Make it easy with bash command.
The command:
read -p "time: " time;while true; do file=<file_name>;m1=$(md5sum $file) | awk '{print $1}';sleep $time;m2=$(md5sum $file | awk '{print $1}');if [ $m1 != $m2 ]; then echo -n "File changed - ";else echo -n "file didn't change - ";date "+%H:%M:%S";done
If you chose 20 for time, it will give you output like this:
File changed - 13:51:45
File changed - 13:52:05
File changed - 13:52:25
File didn't change - 13:52:45
File didn't change - 13:53:05
....
You are asked for the time you want to wait between checks of the file content. Just wait until you had enough
"File didn't change" and cut the command off, and you know the file didn't change.
I, for example chose 20 (The amount of seconds to wait) and just waited for all my screen to be
"File didn't change". That was enough for me to conclude that the log stopped changing, meaning it not being written to anymore.
11.10.2022 - 19:23 - Tuesday
If you ever wanted to search in a specific directory but not in a subdirectory of it, there is a good and easy way to do that.
Use find command with -not -path <path> patameters, to exclude a path from searching in it.
How to use these parameters:
find . -iname file1 -not -path "./dir1/dir2/dir3" - Search for file1, excluding the path ./dir/dir2/dir3.
If you want something more general, like all the paths that contains dir1/dir2 you should do:
find . -iname file1 -not -path "*/dir1/dir2/*"
In general, it is a regular expression, and you can write whatever expression you want and it will be ignored in the search.
30.08.2022 - 14:12 - Tuesday
Like most of linux guys, I used to work with more and less commands, everytime I wanted to inspect an output.
After a while, when you get use to linux, it becomes exhusting using the mouse, scroller and any other graphical tool for it.
Then VIM get into action.
When you get familiar with vim commands ,there's a way to use it as an output inspection tool.
Just redirect the output of any command to vim and you will see the output in vim.
vim <(<command>)
Now you can inspect the output with vim commands and in general work with it as you would working with a file, but its NOT
Just get out of it and the file will not be saved.
If you do want to save it, get into command mode in vim and do the command :saveas <path>
Where path is the full path where you want to save the file.
28.08.2022 - 19:07 - Sunday
Everyone know the basic use of sed and tail.
Not everyone know, or use regularly a very helpful vairant of them.
You probably got to a situation where you wanted to print all line but multiple lines at the start or at the begining of some output.
Well, there's a way to do that, and it very very easy.
Print all lines from i-th line to the end:
cat file | tail -n +<i>
Print all lines from first line to n-i line:
cat file | head -n -<i>
22.08.2022 - 19:07 - Monday
Did you ever got to a situation where your screen is messed up with lines that contain "\t\n" and you just don't understand anything?
Well, the next little trick can help you handle that.
I had pod logs that contained some spring application errors. It was failing the pod, so it was very important to understand what they mean.
They were in a huge line that contained all the java error, I thought only superhuman can understand that.
So instead of manipulating the line with some linux tools, like
sed,
awk and such (which is what most people in my work do)
I just used
printf to wrap the command:
printf "$(kubectl logs $(kubectl get pods | grep <pod_name> | awk '{print $1}'))"
The output showed me a beautiful java error :)
That I still didn't understand :(
---
09.04.2023 - 18:41 - Sunday
you might get to a situation where you have some unprintable characters.
It might fail the command with the error:
-bash : printf --:invalid option
printf: usage printf [-v var] format [arguments]
In this case as you can see the error was
- somewhere where it shouldn't be.
In some outputs its very logical to get '-' or '--'.
So to overcome this is with:
>> printf -- "$(<command>)"
'--' Before the command means that everything after this is the literal character it is, not evaluated, meaning it will be treated as literal
If you try this after this kind of errors it will succeed.
And if not, for now I still didin't encounter this situation :).
Raise it to me, or when I'll find it I'll write about it here.
21.08.2022 - 19:07 - Sunday
If you had a project where you have to change a lot of branches, back and forth and to the sides, its very hard to track what branch you are one.
So each time you have to do a command
git branch, or any other way.
There is a way to solve it.
Source this function in
~/.bashrc file or whenver you want to use it:
parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}
and define the env var
PS1 env variable this way:
export PS1=">>$(parse_git_branch):"
If you are inside a repo in a branch called "branchy1", your prompt will look like this:
>>(branchy1):
This capability can be used for a whole lot of other functions, just think of one and try it
25.06.22 - 16:44 - Saturday
Did you ever had a situation where you needed some long string in your command line, or just an easier way to write variable in your cli?
Well, there's a way to do that.
Use <<EOF and the command line will ask you for that!
HOW TO DO THAT?
Multiline string as a shell variable:
$ sql=$(cat <<EOF
> SELECT foo, bar from db
> WHERE foo='baz'
> EOF
> )
$sql will contain the whole query as a text
Pass multi-line string to a file with redirection
$ cat <<EOF > print.sh
> #!/bin/bash
> echo \$PWD
> echo $PWD
> EOF
The file print.sh will contain whatever is written in the multiline lines
Pass multi-line string to pipe in bash - content after line is sent to cat
cat <<EOF | grep 'b' | tee b.txt
> foo
> bab
> hyu
> jabar
Of the lines written to the multiline string, only the line that
have b in them will be printed to the file b.txt and to the screen, with tee command
19.05.2022 - 16:09 - Thursday
Did you ever had to refresh the screen multiple times to see the result?
For example when you started a machine in the cloud and wanted to get to "working" state, but you had to press refresh time and time again.
Each time you have to take the cursor from where you are to the place where the refresh is and come back to where you were before.
In addition, you had to change context multiple times.
There's a script you can use to do that
here
First of all install xdotool
>> apt install xdotool
>> read -r cx cy < <(xdotool getmouselocation | awk -F'[ :]' '{print $2 , $4}') - Read from mouslocation, current x and y. This command reads first two variables that comes from the command in the parentheses.
Then you are asked to move to the location in the screen where you want to click multiple times
>> read -r gx gy < <(xdotool getmouselocation | awk -F'[ :]' '{print $2 , $4}') - Take the coordinates where you want to go
>> xdotool mousemove $cx $cy - Move to where the script was started - current place
Then you are asked for the delay between clicks.
In the end, a while loop that take saves your current place, as above, and moves back and forth between your current place and the goto place in intermission of the time you mentioned for delay.
14.05.2022 - 19:37 - Saturday
When you start writing a command and in the middle of it you realize that you need something from other command, som output.
What I used to do is to do ctrl+c and do the other command I need, and then start writing the command again.
This can get very frustrating if you wrote a very long command
Solution: Go to the begining of the line with ctrl+a and put '#'. Press enter and you have the command saved in your history to use whenever you want.
For example, in the middle of this command you realized you need some other security group with some id
:
>> aws ec2 create-security-group --group-name my-sg --description "My security group"
So you do ctrl+a then '#' and then Enter:
>> #aws ec2 create-security-group --group-name my-sg --description "My security group"
>>
Search for the group you need:
>> aws ec2 describe-security-groups --query "SecurityGroups[*].{Name:GroupName,ID:GroupId}" | grep <num>
Then you go just one command up in history and can fill in the blank
14.05.2022 - 19:50 - Saturday
When you work with linux, a lot of times you have to copy someoutput to use it somewhere else. Not just redirecting, woe piping which is easy, but take the output and put it in some other application.
Most of the time you have to do it by hand, and it might get exhuasting if you have to copy a lot of text to some mail or other GUI application.
The solution: Create an alias that uses a command that knows how to work with clipboard, that takes the output from the command and put it in clipboard automatically.
The command is xclip.
There are 2 options for the alias, one with new line copied and one without(The output have new-line character in the end):
>> alias cp2clip='xclip -selection clipboard'
>> alias cp2clip-nonl="tr -d '\n' | xclip -selection clipboard"
Now it can be used piped to some other command to get its output to the clipboard:
>> echo "some thing to copy to blipboard" | cp2clip
Now you can use
ctrl+v to paste it wherever you want
new post for new tricks