====== Shell Scripts usage ======
\\
===== Websites =====
Color codes : http://misc.flogisoft.com/bash/tip_colors_and_formatting\\
Text to ascii generator : http://patorjk.com/software/taag/#p=display&f=Graffiti&t=Type%20Something\\
===== Function to check exit code =====
function test {
"$@"
local status=$?
if [ $status -ne 0 ]; then
echo "error with $1" >&2
fi
return $status
}
test command1
From http://stackoverflow.com/questions/5195607/checking-bash-exit-status-of-several-commands-efficiently
===== Ascii Art Bash =====
The aim here was to use the following ascii art :
P___----....
! __
' ~~ ---.#..__ ` ~ ~ - - . .:
` ~~--. .F~~___-__.
; , .- . _!
, ' ; ~ .
, ____ ; ' _ ._ ;
,_ . - '___#, ~~~ ---. _, . ' .#' ~ .;
=---==~~~ ~~~==--__ ; '~ -. ,#_ .'
' `~=.; ` /
' ' '.
' '
\ ' ' '
`.`\ ' . ; ,
\ ` ' ' ;
; ' ' '
/_ ., / __...---./ '
',_, __.--- ~~;#~ --..__ _'.-~;# // `.'
/ / ~~ .' . #; ~~ /// #; // /
/ ' . __ . ' ;#;_ . ////.;#;./ ; /
\ . / ,##' / _ /. '(/ ~||~\'
\ ` - . /_ . -==- ~ ' / (/ ' . ;;. ',
/' . ' -^^^...--- ``(/' _ ' '' `,;
##,. .#...( ' .c c .c c c. '.. ;; ../
%%#%;,..##.\_ ,;###;,. ;;.:##;,. raf
%%%%########%%%%;,.....,;%%%%%%;,.....,;%%%%%%%%%%%%%%%%%%%%............
Into the bashrc at login, but only in interactive mode, and using colors. To use colors, you need to use **echo -e**, however, you will face difficulties with special characters. An excellent way around I found (do not remember where) was to use variables to bypass the problem. The only variable to modify is `, change them by ' :
if [ "$PS1" ]; then
echo
echo
toto=" P___----...."
echo -e "$toto"
toto=' ! __'
echo -e "$toto"
toto=" ' ~~ ---.#..__ ' ~ ~ - - . .:"
echo -e "$toto"
toto=" ' "
toto0="_"
toto1=" ~~--. .F~~___-__."
echo -e "$toto\e[1m\e[38;5;202m$toto0\e[0m$toto1"
toto=" ; "
toto0="/_| _ / _ _"
toto1=" , .- . _! "
echo -e "$toto\e[1m\e[38;5;202m$toto0\e[0m$toto1"
toto=" , "
toto0="( |//)()/ (-"
toto1=" ' ; ~ ."
echo -e "$toto\e[1m\e[38;5;202m$toto0\e[0m$toto1"
toto=" , ____ ; ' _ ._ ; "
echo -e "$toto"
toto=" ,_ . - '___#, ~~~ ---. _, . ' .#' ~ .;"
echo -e "$toto"
toto=" =---==~~~ ~~~==--__ ; '~ -. ,#_ .'"
echo -e "$toto"
toto=" ' '~=.; ' /"
echo -e "$toto"
toto=" ' ' '. "
echo -e "$toto"
toto=" ' ' "
echo -e "$toto"
toto=" \ ' ' '"
echo -e "$toto"
toto=" '.'\ ' . ; ,"
echo -e "$toto"
toto=" \ ' ' Experimental ' ;"
echo -e "$toto"
toto=" ; ' Cluster ' '"
echo -e "$toto"
toto=" /_ ., / __...---./ '"
echo -e "$toto"
toto=" ',_, __.--- ~~;#~ --..__ _'.-~;# // '.'"
echo -e "$toto"
toto=" / / ~~ .' . #; ~~ /// #; // /"
echo -e "$toto"
toto=" / ' . __ . ' ;#;_ . ////.;#;./ ; /"
echo -e "$toto"
toto=" \ . / ,##' / _ /. '(/ ~||~\'"
echo -e "$toto"
toto=" \ ' - . /_ . -==- ~ ' / (/ ' . ;;. ', "
echo -e "$toto"
toto=" /' . ' -^^^...--- ''(/' _ ' '' ',;"
echo -e "$toto"
toto="##,. .#..."
toto0="( ' .c c .c c c. '"
toto1=".."
toto2=" ;; "
toto3=".."
toto4="/ "
echo -e "\e[1m\e[38;5;27m$toto\e[0m$toto0\e[1m\e[38;5;27m$toto1\e[0m$toto2\e[1m\e[38;5;27m$toto3\e[0m$toto4"
toto="%%#%;,..##."
toto0="\_ "
toto1=",;###;,."
toto2=" ;;"
toto3=".:##;,. raf"
echo -e "\e[1m\e[38;5;27m$toto\e[0m$toto0\e[1m\e[38;5;27m$toto1\e[0m$toto2\e[1m\e[38;5;27m$toto3\e[0m"
toto="%%%%########%%%%;,.....,;%%%%%%;,.....,;%%%%%%%%%%%%%%%%%%%%............"
echo -e "\e[1m\e[38;5;27m$toto\e[0m"
echo
echo
fi;
Add this into your .bashrc or in the /etc/bashrc for all users, and you obtain the following result :
{{ :software:system:allhailstoamber.png |}}
===== Ascii symbols =====
All :
๑•ิ.•ั๑ ๑۩۞۩๑ ♬✿.。.:* ★ ☆ εїз℡❣·۰•●○●ōゃ ♥ ♡๑۩ﺴ ☜ ☞ ☎ ☏♡ ⊙◎ ☺ ☻✖╄ஐﻬ ► ◄ ▧ ▨ ♨ ◐ ◑ ↔ ↕ ▪ ▫ ☼ ♦ ▀ ▄ █▌
▐░ ▒ ▬♦ ◊ ◦ ☼ ♠♣ ▣ ▤ ▥ ▦ ▩ ◘ ◙ ◈ ♫ ♬ ♪ ♩ ♭ ♪ の ☆ → あ ぃ £ ❤# @ & * ❁ ❀ ✿ ✾ ❃ ✺ ❇ ❈ ❊ ❉ ✱ ✲ ✩ ✫
✬ ✭ ✮ ✰ ☆ ★ ✪ ¤ ☼ ☀ ☽ ☾ ❤ ♡ ღ☻ ☺ ❂ ◕ ⊕ ☉ Θ o O ♋ ☯ ㊝ ⊙ ◎◑ ◐ ۰ • ● ▪ ▫ 。 ゚ ๑ ☜ ☞ ☂ ♨ ☎ ☏ × ÷ = ≠
≒ ∞ ˇ ± √ ⊥▶ ▷ ◀ ◁ ☀ ☁ ☂ ☃ ☄ ★ ☆ ☇ ☈ ☉ ☊ ☋ ☌ ☍ ☑ ☒☢ ☸ ☹ ☺ ☻ ☼ ☽ ☾ ♠ ♡ ♢ ♣ ♤ ♥ ♦ ♧ ♨ ♩ ✙ ✈ ✉ ✌ ✁
♝ ♞♯♩♪♫♬♭♮ ☎ ☏ ☪ ♈ ♨ ₪ ™ ♂✿ ♥ の ↑ ↓ ← → ↖ ↗ ↙ ↘ ㊣ ◎ ○ ● ⊕ ⊙ ○ △ ▲ ☆ ★ ◇ ◆ ■ □ ▽ ▼ § ¥ 〒 ¢ £ ※
♀ ♂ &⁂ ℡ ↂ░ ▣ ▤ ▥ ▦ ▧ ✐✌✍✡✓✔✕✖ ♂ ♀ ♥ ♡ ☜ ☞ ☎ ☏ ⊙ ◎ ☺ ☻ ► ◄ ▧ ▨ ♨ ◐ ◑ ↔ ↕ ♥ ♡ ▪ ▫ ☼ ♦ ▀ ▄ █ ▌ ▐
░ ▒ ▬ ♦ ◊ ◘ ◙ ◦ ☼ ♠ ♣ ▣ ▤ ▥ ▦ ▩ ◘ ◙ ◈ ♫ ♬ ♪ ♩ ♭ ♪ ✄☪☣☢☠░ ▒ ▬ ♦ ◊ ◦ ♠ ♣ ▣ ۰•● ❤ ●•۰► ◄ ▧ ▨ ♨ ◐ ◑ ↔ ↕
▪ ▫ ☼ ♦♧♡♂♀♠♣♥❤☜☞☎☏⊙◎ ☺☻☼▧▨♨◐◑↔↕▪ ▒ ◊◦▣▤▥ ▦▩◘ ◈◇♬♪♩♭♪の★☆→あぃ£Ю〓§♤♥▶¤๑⊹⊱⋛⋌⋚⊰⊹ ๑۩۩.. ..۩۩๑
๑۩۞۩๑ ✲ ❈ ✿ ✲ ❈ ➹ ~.~ ◕‿- ❣ ✚ ✪ ✣ ✤ ✥ ✦❉ ❥ ❦ ❧ ❃ ❂ ❁ ❀ ✄ ☪ ☣ ☢ ☠ ☭ღღღ ▶ ▷ ◀ ◁ ☀ ☁ ☂ ☃ ☄ ★
☆ ☇ ☈ ⊙ ☊ ☋ ☌ ☍ⓛⓞⓥⓔ๑•ิ.•ั๑ ๑۩۞۩๑ ♬✿ ☉♡ ♢ ♣ ♤ ♥ ♦ ♧ ♨ ♩ ✙✈ ✉ ✌ ✁ ✎ ✐ ❀ ✰ ❁ ❤ ❥ ❦❧ ➳ ➽
εїз℡❣·۰•●○●ゃōゃ♥ ♡๑۩ﺴ ☜ ☞ ☎ ☏♡ ⊙◎ ☺ ☻✖╄ஐﻬ ► ◄ ▧ ▨ ♨ ◐ ◑ ↔ ↕ ▪ ▫ ☼ ♦ ▀ ▄ █▌ ▐░ ▒ ▬♦ ◊ ◦ ☼ ♠♣ ▣ ▤ ▥ ▦
▩ ◘ ◙ ◈ ♫ ♬ ♪ ♩ ♭ ♪ の ☆ → あ ぃ £ ❤ ❁ ❀ ✿ ✾ ❃ ✺ ❇ ❈ ❊ ❉ ✱ ✲ ✩ ✫ ✬ ✭ ✮ ✰ ☆ ★ ✪ ¤ ☼ ☀ ☽ ☾ ❤ ♡ ღ☻
☺ ❂ ◕ ⊕ ☉ Θ o O ♋ ☯ ㊝ ⊙ ◎ ◑ ◐ ۰ • ● ▪ ▫ 。 ゚ ๑ ☜ ☞ ☂ ♨ ☎ ☏▶ ▷ ◀ ◁ ☀ ☁ ☂ ☃ ☄ ★ ☆ ☇ ☈ ☉ ☊ ☋ ☌ ☍ ☑
☒☢ ☸ ☹ ☺ ☻ ☼ ☽ ☾ ♠ ♝ ♞♯♩♪♫♬♭♮ ☎ ☏ ☪ ♈ ♨ ºº ₪ ¤ 큐 « »™ ♂✿ ♥ の ↑ ↓ ← → ↖ ↗ ↙ ↘ ㊣ ◎ ○ ● ⊕ ⊙ ○ △ ▲
☆ ★ ◇ ◆ ■ □ ▽ ▼ § ¥〒 ¢ £ ※ ♀ ♂ © ® ⁂ ℡ ↂ░ ▣ ▤ ▥ ▦ ▧ ✐✌✍✡✓✔✕✖ ♂ ♀ ♥ ♡ ☜ ☞ ☎ ☏ ⊙ ◎ ☺ ☻ ► ◄ ▧ ▨
♨ ◐ ◑ ↔ ↕ ♥ ♡ ▪ ▫ ☼ ♦ ▀ ▄ █ ▌ ▐ ░ ▒ ▬ ♦ ◊ ◘ ◙ ◦ ☼ ♠ ♣ ▣ ▤ ▥ ▦ ▩ ◘ ◙ ◈ ♫ ♬ ♪ ♩ ♭ ♪ ✄☪☣☢☠㊊㊋㊌㊍㊎㊏ ㊐㊑
㊒㊓㊔㊕㊖㊗㊘㊜㊝㊞㊟㊠㊡㊢ ㊣㊤㊥㊦㊧㊨㊩㊪㊫㊬㊭㊮㊯㊰✗✘✚✪✣✤✥✦✧✩✫✬✭✮✯✰ ✱✲✳❃❂❁❀✿✾✽✼✻✺✹✸✷
✶✵✴❄❅❆❇❈❉❊❋❖☀☂☁【】┱ ┲ ❣ ✪ ✣ ✤ ✥ ✦ ❉ ❥ ❦ ❧ ❃ ❂ ❁ ❀ ✄ ☪ ☣ ☢ ☠ ☭ ♈ ➸ ✓ ✔ ✕ ✖ .: ◢ ◣ ◥ ◤ ▽ ▧
▨ ▣ ▤ ▥ ▦ ▩ ◘ ◙ ▓ ▒ ░ ™ ℡ 凸 の ๑۞๑ ๑۩ﺴ ﺴ۩๑ o(‧”’‧)o ❆ べò⊹⊱⋛⋋ ⋌⋚⊰⊹ ⓛⓞⓥⓔ ☀ ☼ ☜ ☞ ⊙® ◈ ♦ ◊ ◦ ◇ ◆
εїз❃❂❁❀✿✾✽✼✻✺✹✸✷ ✶✵✴❄❅❆❇❈❉ ❊❋❖❤❥❦❧↔ ↕ ▪ → ︷╅╊✿ (¯`•._.• •._.•´¯)(¯`•¸•´¯) ❤`•.¸¸.•´´¯`••
.¸¸.•´¯`•.•●•۰• ••.•´¯`•.•• ••.•´¯`•.••—¤÷(`[¤* *¤]´)÷¤——(•·÷[ ]÷·•)— ①②③④⑤⑥⑦⑧⑨⑩ ⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳ ⒶⒷⒸⒹⒺⒻ
ⒼⒽⒾⒿⓀⓁ ⓂⓃⓄⓅⓆⓇ ⓈⓉⓊⓋⓌⓍ ⓎⓏ ⓐⓑⓒⓓⓔⓕ ⓖⓗⓘⓙⓚⓛ ⓜⓝⓞⓟⓠⓡ ⓢⓣⓤⓥⓦⓧ ⓨⓩ(⊙▂⊙✖ )(づ  ̄ ³ ̄)づ
( c//”-}{-*\x)(-’๏_๏’-)(◐ o ◑ )(⊙…⊙ )๏[-ิ_•ิ]๏(•ิ_•ิ)(•ิ_•ิ) (/•ิ_•ิ)(︶︹︺)
Arrows:
← ↑ → ↓ ↔ ↕ ↖ ↗ ↘ ↙ ↚ ↛ ↜ ↝ ↞ ↟
↠ ↡ ↢ ↣ ↤ ↥ ↦ ↧ ↨ ↩ ↪ ↫ ↬ ↭ ↮ ↯
↰ ↱ ↲ ↳ ↴ ↵ ↶ ↷ ↸ ↹ ↺ ↻ ↼ ↽ ↾ ↿
⇀ ⇁ ⇂ ⇃ ⇄ ⇅ ⇆ ⇇ ⇈ ⇉ ⇊ ⇋ ⇌ ⇍ ⇎ ⇏
⇐ ⇑ ⇒ ⇓ ⇔ ⇕ ⇖ ⇗ ⇘ ⇙ ⇚ ⇛ ⇜ ⇝ ⇞ ⇟
⇠ ⇡ ⇢ ⇣ ⇤ ⇥ ⇦ ⇧ ⇨ ⇩ ⇪ ⇫ ⇬ ⇭ ⇮ ⇯
⇰ ⇱ ⇲ ⇳ ⇴ ⇵ ⇶ ⇷ ⇸ ⇹ ⇺ ⇻ ⇼ ⇽ ⇾ ⇿
⟰ ⟱ ⟲ ⟳ ⟴ ⟵ ⟶ ⟷ ⟸ ⟹ ⟺ ⟻ ⟼ ⟽ ⟾ ⟿
⤀ ⤁ ⤂ ⤃ ⤄ ⤅ ⤆ ⤇ ⤈ ⤉ ⤊ ⤋ ⤌ ⤍ ⤎ ⤏
⤐ ⤑ ⤒ ⤓ ⤔ ⤕ ⤖ ⤗ ⤘ ⤙ ⤚ ⤛ ⤜ ⤝ ⤞ ⤟
⤠ ⤡ ⤢ ⤣ ⤤ ⤥ ⤦ ⤧ ⤨ ⤩ ⤪ ⤫ ⤬ ⤭ ⤮ ⤯
⤰ ⤱ ⤲ ⤳ ⤴ ⤵ ⤶ ⤷ ⤸ ⤹ ⤺ ⤻ ⤼ ⤽ ⤾ ⤿
⥀ ⥁ ⥂ ⥃ ⥄ ⥅ ⥆ ⥇ ⥈ ⥉ ⥊ ⥋ ⥌ ⥍ ⥎ ⥏
⥐ ⥑ ⥒ ⥓ ⥔ ⥕ ⥖ ⥗ ⥘ ⥙ ⥚ ⥛ ⥜ ⥝ ⥞ ⥟
⥠ ⥡ ⥢ ⥣ ⥤ ⥥ ⥦ ⥧ ⥨ ⥩ ⥪ ⥫ ⥬ ⥭ ⥮ ⥯
⥰ ⥱ ⥲ ⥳ ⥴ ⥵ ⥶ ⥷ ⥸ ⥹ ⥺ ⥻ ⥼ ⥽ ⥾ ⥿
Geometric shapes:
■ □ ▢ ▣ ▤ ▥ ▦ ▧ ▨ ▩ ▪ ▫ ▬ ▭ ▮ ▯
▰ ▱ ▲ △ ▴ ▵ ▶ ▷ ▸ ▹ ► ▻ ▼ ▽ ▾ ▿
◀ ◁ ◂ ◃ ◄ ◅ ◆ ◇ ◈ ◉ ◊ ○ ◌ ◍ ◎ ●
◐ ◑ ◒ ◓ ◔ ◕ ◖ ◗ ◘ ◙ ◚ ◛ ◜ ◝ ◞ ◟
◠ ◡ ◢ ◣ ◤ ◥ ◦ ◧ ◨ ◩ ◪ ◫ ◬ ◭ ◮ ◯
◰ ◱ ◲ ◳ ◴ ◵ ◶ ◷ ◸ ◹ ◺ ◻ ◼ ◽ ◾ ◿
===== Ascii japanese emoticons =====
╮(─▽─)╭ ¯\_(ツ)_/¯ ٩(-̮̮̃-̃)۶
ヽ(´ー`)┌ ┗┐ヽ(′Д、`*)ノ┌┛ ヽ( ´¬`)ノ
┗┃・ ■ ・┃┛ ヾ(´A`)ノ゚ ヽ(・_・;)ノ
ヽ(  ̄д ̄;)ノ \(〇_o)/ ヽ(。_°)ノ
\(;´□`)/ ヾ(*´ー`)ノ ヽ(‘ー`)ノ
ヽ(ー_ー )ノ ヽ(´~`;) ┐(‘~`;)┌
ヽ(*ω。)ノ (;´・`)> (^~^)
٩(-̮̮̃•̃)۶ ┐( ̄ー ̄)┌ t(ツ)_/¯
┐( ̄ヮ ̄)┌ ╰( ´◔ ω ◔ `)╯ ಠ_ಠ
ლ(ಠ_ಠლ) ¯\(°_o)/¯ ╮(╯▽╰)╭
\\
===== Simulating kghostview with okular =====
When using tools like KCacheGrind, you will encounter difficulties because KGhostView has been replaced by Okular. To bypass it, and make your tools use Okular: (note that this "bypass" can be used with all programs, including compilers!)
mkdir $HOME/bin
touche $HOME/bin/kghostview
edit the file, using vim for example :
vim $HOME/bin/kghostview
add :
#!/bin/bash
okular "$@"
save and close, and make it executable :
chmod +x $HOME/bin/kghostview
add it to your PATH :
export PATH=$HOME/bin/:$PATH
Now you can use KCacheGrind or other tools that need to use KGhostView, they will use okular instead.
===== Redirection =====
Redirect everything to file, even when using make or configure :
> output.txt 2>&1
To add a string at the end of file (for example, adding an export at the end of your bashrc to make it permanent) :
echo 'export PATH=/soft/gnuplot-4.4/bin:$PATH' >> ~/.bashrc
General redirection table :
^ Character ^ Action ^
| > | Redirect standard output |
| >& | Redirect standard output and standard error |
| < | Redirect standard input |
| >! | Redirect standard output; overwrite file if it exists |
| >&! | Redirect standard output and standard error; overwrite file if it exists |
| > > | Append standard output |
| > > filename 2>&1 | Append standard output and standard error |
===== Multiple tasks =====
To wget multiple of files at once, if the files have the same names and differ only by a numerous, and if you are using bash > 4.0 :
wget http://theadress.com/thegile{001..030}.dat
===== Loops and if =====
Read a file line per line, line is stored in $line, and work on values (users), a progress is displayed :
while read line
do
compteur=$(expr $compteur + 1)
echo -ne "User $compteur/$nb_ldap_users\r"
# Get ids
user_uid=$(id "$line" | awk -F'(' '{print $2;}' | awk -F')' '{print $1;}')
user_gid=$(id "$line" | awk -F'(' '{print $3;}' | awk -F')' '{print $1;}')
# Get home from passwd
user_home=$(getent passwd "$line" | cut -d: -f6)
# Get real home position
# First check if home exist
ls -l "$user_home" 2>> errors > /dev/null
if [ $? -eq 0 ];then
user_home_real=$(ls -l "$user_home" | awk -F' ' '{print $10;}')
# Get real home uid and gid and check them
user_home_real_uid=$(ls -ld $user_home_real | awk -F' ' '{print $3;}')
user_home_real_gid=$(ls -ld $user_home_real | awk -F' ' '{print $4;}')
# check
if [ "$user_uid" != "$user_home_real_uid" ]; then
echo "Bad home uid for user $line. Real : $user_uid, got : $user_home_real_uid " >> errors
fi
if [ "$user_gid" != "$user_home_real_gid" ]; then
echo "Bad home gid for user $line. Real : $user_gid, got : $user_home_real_gid " >> errors
fi
else
echo "Could not find home for user $line" >> errors
fi
# Write result
echo $line $user_gid $user_home $user_home_real $user_home_real_uid $user_home_real_gid >> result
done < ldap_users
echo -ne '\n'
Now, using the same, to get the size of all repertories listed in a text file :
rm size.txt; compteur=0
# Get informations on user
while read line
do
compteur=$(expr $compteur + 1)
echo -ne "User $compteur/516\r"
du -ch -sB K "$line" | grep total | awk -F' ' '{print $1;}' >> size.txt
done < home_users_nr_d
echo -ne '\n'
All size are noted like "132K\n", easy to manipulate after.
===== Basis =====
==== sed and awk ====
In a shell, you can 'pipe' output to another command. tutu.dat contains :
Y X
1.2 3.4
2.3 3.5
-0.6 3.6
To extract the value 2.3 :
grep 3.4 tyty
Result :
1.2 3.4
To take only the first value (1.2), ask awk to keep only the first value of the line :
grep 3.4 tyty | awk -F' ' '{print $1;}'
Result :
1.2
If the separator is different: echo "1.2/1.3" | awk -F'/' '{print $1;}', it still gives 1.2.
To sum all values of the first row : two ways, remove the first line when piping, or remove all lines using symbol Y for example.
First way :
sed '1d' tyty
Result :
1.2 3.4
2.3 3.5
-0.6 3.6
(of course, replace 1d with 2d for second line, or with '5,10d' for lines 5 and 10, etc)
Second way :
grep -v 'Y' tyty
Result :
1.2 3.4
2.3 3.5
-0.6 3.6
Note that to add another string, use \| :
grep -v 'Y\|1.2' tyty
Result :
2.3 3.5
-0.6 3.6
Then, pipe it on awk to recover only first row :
grep -v 'Y' tyty | awk -F' ' '{print $1;}'
Result :
1.2
2.3
-0.6
Then, you want all of this to be the same as an addition expression, compatible with bc command (the gnu calculator).
grep -v 'Y' tyty | awk -F' ' '{print $1;}' | paste -sd+
Result :
1.2+2.3+-0.6
Of course, using -sd* will give you 1.2*2.3*-0.6, etc.
Last step is to pipe it to bc :
grep -v 'Y' tyty | awk -F' ' '{print $1;}' | paste -sd+ | bc
Result :
2.9
Tip: do no try to merge steps. You can do very shorts commands that do the same thing. Very useful to show off, but bad idea to explain to others, to recover a single step, or simply to remember how it works few months later.
To put this into a variable :
myvalue=$( grep -v 'Y' tyty | awk -F' ' '{print $1;}' | paste -sd+ | bc )
echo $myvalue should give 2.9.
==== Loops ====
In bash, there are multiple ways to use loops, by I prefer to use the way like C :
#!/bin/bash
for (( c=1; c<=5; c++ ))
do
echo "Welcome $c times"
done
#!/bin/bash
for (( c=2; c<=10; c=c+2 ))
do
echo "Welcome $c times"
done
etc. Use if statement to break the loop :
if [[ $myvalue == 0 ]]
then
echo "Test $c Passed"
break
else
echo "Test $c Failed, Restart"
fi
In this example, we can start a program, and recover its exit statue to check if it executed and exited normally. Then, we break the loop if yes, or we restart it if no.
for (( c=1; c<=30; c++ )) # 30 Tests
do
grep -i "$c" Test
RETVAL=$?
if [[ $RETVAL == 0 ]]
then
echo "Test $c Passed"
break
else
echo "Test $c Failed, Restart"
fi
done
$? contains the value of the exist status of the last command.
==== Arguments ====
If you want to pass variables/arguments to launched/son scripts, and recover variables from them.
Consider the following script, in myscript.sh (do not forget to do a chmod +x to execute it):
In_Buffer="$@"
val1=$( echo $In_Buffer | awk '{print $1;}')
val2=$( echo $In_Buffer | awk '{print $2;}')
val3=$( echo $In_Buffer | awk '{print $3;}')
echo $val1 $val2 $val3
./myscript.sh
give nothing.
./myscript.sh 10 13 16 9
returns :
10 13 16
The son's script has recovered the values. They can be seen has subroutine/function arguments.
Now, to return values, just do a final echo in the son script, using a special word, let's say "SON_RETURN".
In_Buffer="$@"
val1=$( echo $In_Buffer | awk '{print $1;}')
val2=$( echo $In_Buffer | awk '{print $2;}')
val3=$( echo $In_Buffer | awk '{print $3;}')
echo $val1 $val2 $val3
sumval=$(echo "$val1+$val2+$val3" | bc)
echo '\nSON_RETURN' $sumval
Now, using the command you get :
./myscript.sh 10 13 16
10 13 16
\nSON_RETURN 39
You can then recover this result to a variable :
returnval=$(./myscript.sh 10 13 16)
then
echo -e $returnval | grep 'SON_RETURN'
SON_RETURN 39
So a simple awk will allow you to extract 39 or other returned variables. Note that the -e argument to echo allow the \n character to be used has a return. Without it, the grep could not work properly.
==== plot ====
Now, I want to use gnuplot to plot things into png files. You can use everything seen before to create gnuplot scripts, and launch them.
Suppose we want to plot the tyty file seen above.
Create a file "gnuplotscript", and add :
# Set png terminal and png size
set terminal png size 640,480
# Set output file name
set output 'myfile.png'
# Ask gnuplot to use first line as title name
set key autotitle columnhead
# Plot (exit automaticaly after)
plot 'tyty' with line
Now, use gnuplot :
gnuplot gnuplotscript
And it will output your graph in png.
===== Monitor using bash =====
I present here a small project I worked on. The idea was to be able to monitor multiple systems, using only simple user accounts and without installing anything on remote machines. This script had to render everything in HTML, and had to actualise information every 15 minutes.
==== Acquire information ====
First, we need to acquire infos on the system :
Date :
current_date=$(date +"%s")
Network :
- ipv4 and ipv6 in and out :
ipv4_in=$( echo "`egrep -v bond\|lo\|face\|Inter /proc/net/dev | awk -F' ' '{print $2;}' | paste -sd+ | bc` * 8" | bc )
ipv4_out=$( echo "`egrep -v bond\|lo\|face\|Inter /proc/net/dev | awk -F' ' '{print $10;}' | paste -sd+ | bc` * 8" | bc )
ipv6_in=$( echo "`egrep Ip6InOctets /proc/net/snmp6 | awk -F' ' '{print $2;}'` * 8" | bc )
ipv6_out=$( echo "`egrep Ip6OutOctets /proc/net/snmp6 | awk -F' ' '{print $2;}'` * 8" | bc )
totalip_in=$( echo "$ipv4_in + $ipv6_in" | bc )
totalip_out=$( echo "$ipv4_out + $ipv6_out" | bc )
totalip_in=$( echo "$totalip_in*0.001" | bc ) # in Kilooctets (from Octets)
totalip_out=$( echo "$totalip_out*0.001" | bc ) # in Kilooctets (from Octets)
Flux if you now the previous get :
difftotalip_in=$( echo "scale=4;( $totalip_in - $previous_totalip_in ) / ( $current_date - $previous_date )" | bc) # in Ko/s
difftotalip_out=$( echo "scale=4;( $totalip_out - $previous_totalip_out ) / ( $current_date - $previous_date )" | bc) # in Ko/s
Ssh :
Number of correct connexions for the user spheniscus :
grep -i "spheniscus" /var/log/auth.log | wc -l
Number of invalid user authentications and failed password :
grep -i "Invalid user" /var/log/auth.log | wc -l
grep -i "Failed password" /var/log/auth.log | wc -l
I/O :
Total HDD I/O :
totalio_write=$(echo "`grep -i "sda " /proc/diskstats | awk '{print $10;}'` * 512 * 0.001" | bc) # In Ko
totalio_read=$(echo "`grep -i "sda " /proc/diskstats | awk '{print $6;}'` * 512 * 0.001" | bc) # In Ko
Flux if you now the last get :
difftotalio_write=$( echo "scale=4;( $totalio_write - $previous_totalio_write ) / ( $current_date - $previous_date )" | bc) # in Ko/s
difftotalio_read=$( echo "scale=4;( $totalio_read - $previous_totalio_read ) / ( $current_date - $previous_date )" | bc) # in Ko/s
CPU :
cpu_idle=$( echo "`top -b -n 5 | grep -i "Cpu(s)" | tr -d '%id,' | awk '{print $2;}' | awk 'NR==5'`");
cpu_used=$( echo "100 - $cpu_idle" | bc )
Memory :
MemTotal=$( echo "`grep -i "MemTotal" /proc/meminfo | tr -d 'kB' | awk '{print $2;}'`")
MemFree=$( echo "`grep -i "MemFree" /proc/meminfo | tr -d 'kB' | awk '{print $2;}'`")
Cached=$( echo "`grep -i "Cached" /proc/meminfo | tr -d 'kB' | awk '{print $2;}' | awk 'NR==1'`")
Buffers=$( echo "`grep -i "Buffers" /proc/meminfo | tr -d 'kB' | awk '{print $2;}'`")
MemUsed=$( echo "$MemTotal - $MemFree - $Buffers - $Cached" | bc )
MemCached=$( echo "$Buffers + $Cached" | bc )
MemUsed=$( echo "$MemUsed*0.001" | bc ) # in MegaBytes
MemCached=$( echo "$MemCached*0.001" | bc ) # in MegaBytes
MemFree=$( echo "$MemFree*0.001" | bc ) # in MegaBytes
SwapTotal=$( echo "`grep -i "SwapTotal" /proc/meminfo | tr -d 'kB' | awk '{print $2;}'`")
SwapFree=$( echo "`grep -i "SwapFree" /proc/meminfo | tr -d 'kB' | awk '{print $2;}'`")
SwapUsed=$( echo "$SwapTotal - $SwapFree" | bc )
SwapUsed=$( echo "$SwapUsed*0.001" | bc ) # in MegaBytes
==== ssh launch ====
We then launch these information gathering scripts using ssh, and using input and output system seen in the basis section of this page (to keep in memory previous records and date, to evaluate flux for example). I assume you already have a key authentication system for ssh, and that you do not have passphrase (bad idea on a server, but ok four your monitoring station).
The script will be (file name : ssh_llcheck.bash):
# /bin/bash
In_Buffer="$@"
previous_date=$( echo $In_Buffer | awk '{print $1;}')
previous_totalip_in=$( echo $In_Buffer | awk '{print $2;}')
previous_totalip_out=$( echo $In_Buffer | awk '{print $3;}')
previous_totalio_write=$( echo $In_Buffer | awk '{print $4;}')
previous_totalio_read=$( echo $In_Buffer | awk '{print $5;}')
current_date=$(date +"%s")
#
# NETWORK
#
ipv4_in=$( echo "`egrep -v bond\|lo\|face\|Inter /proc/net/dev | awk -F' ' '{print $2;}' | paste -sd+ | bc` * 8" | bc )
ipv4_out=$( echo "`egrep -v bond\|lo\|face\|Inter /proc/net/dev | awk -F' ' '{print $10;}' | paste -sd+ | bc` * 8" | bc )
ipv6_in=$( echo "`egrep Ip6InOctets /proc/net/snmp6 | awk -F' ' '{print $2;}'` * 8" | bc )
ipv6_out=$( echo "`egrep Ip6OutOctets /proc/net/snmp6 | awk -F' ' '{print $2;}'` * 8" | bc )
totalip_in=$( echo "$ipv4_in + $ipv6_in" | bc )
totalip_out=$( echo "$ipv4_out + $ipv6_out" | bc )
totalip_in=$( echo "$totalip_in*0.001" | bc ) # in Kilooctets (from Octets)
totalip_out=$( echo "$totalip_out*0.001" | bc ) # in Kilooctets (from Octets)
difftotalip_in=$( echo "scale=4;( $totalip_in - $previous_totalip_in ) / ( $current_date - $previous_date )" | bc) # in Ko/s
difftotalip_out=$( echo "scale=4;( $totalip_out - $previous_totalip_out ) / ( $current_date - $previous_date )" | bc) # in Ko/s
#
# HARDWARE
#
totalio_write=$(echo "`grep -i "sda " /proc/diskstats | awk '{print $10;}'` * 512 * 0.001" | bc) # In Ko
totalio_read=$(echo "`grep -i "sda " /proc/diskstats | awk '{print $6;}'` * 512 * 0.001" | bc) # In Ko
difftotalio_write=$( echo "scale=4;( $totalio_write - $previous_totalio_write ) / ( $current_date - $previous_date )" | bc) # in Ko/s
difftotalio_read=$( echo "scale=4;( $totalio_read - $previous_totalio_read ) / ( $current_date - $previous_date )" | bc) # in Ko/s
cpu_idle=$( echo "`top -b -n 5 | grep -i "Cpu(s)" | tr -d '%id,' | awk '{print $5;}' | awk 'NR==5'`");
cpu_used=$( echo "100 - $cpu_idle" | bc )
MemTotal=$( echo "`grep -i "MemTotal" /proc/meminfo | tr -d 'kB' | awk '{print $2;}'`")
MemFree=$( echo "`grep -i "MemFree" /proc/meminfo | tr -d 'kB' | awk '{print $2;}'`")
Cached=$( echo "`grep -i "Cached" /proc/meminfo | tr -d 'kB' | awk '{print $2;}' | awk 'NR==1'`")
Buffers=$( echo "`grep -i "Buffers" /proc/meminfo | tr -d 'kB' | awk '{print $2;}'`")
MemUsed=$( echo "$MemTotal - $MemFree - $Buffers - $Cached" | bc )
MemCached=$( echo "$Buffers + $Cached" | bc )
MemUsed=$( echo "$MemUsed*0.001" | bc ) # in MegaBytes
MemCached=$( echo "$MemCached*0.001" | bc ) # in MegaBytes
MemFree=$( echo "$MemFree*0.001" | bc ) # in MegaBytes
SwapTotal=$( echo "`grep -i "SwapTotal" /proc/meminfo | tr -d 'kB' | awk '{print $2;}'`")
SwapFree=$( echo "`grep -i "SwapFree" /proc/meminfo | tr -d 'kB' | awk '{print $2;}'`")
SwapUsed=$( echo "$SwapTotal - $SwapFree" | bc )
SwapUsed=$( echo "$SwapUsed*0.001" | bc ) # in MegaBytes
# First echo, returned variables
echo "$current_date $totalip_in $totalip_out $totalio_write $totalio_read"
# Middle echo, to cut the returned line
echo "Next"
# Second echo, to be written in the Log File
echo "$( date +%Y-%d-%m-%H:%M ) $cpu_used $difftotalip_in $difftotalip_out $MemUsed $MemCached $MemFree $SwapUsed $totalio_write $totalio_read"
Now, you can use an upper script that will call this script for multiple machines, and store information in directories (one per server) :
#!/bin/bash
#
# VARIABLES
#
#TallGeese
TallGeese_previous_date="0"
TallGeese_previous_totalip_in="0"
TallGeese_previous_totalip_out="0"
TallGeese_previous_totalio_write="0"
TallGeese_previous_totalio_read="0"
TallGeese_repertory_name="TallGeese"
TallGeese_login="spheniscus"
TallGeese_ip="tallgeese.fr"
#
# MAIN LOOP
#
while true
do
echo "Check"
# ssh the script
Out_buffer=$(ssh " $TallGeese_login@$TallGeese_ip" 'bash -s' < ssh_llcheck.bash $TallGeese_previous_date $TallGeese_previous_totalip_in \
$TallGeese_previous_totalip_out $TallGeese_previous_totalio_write $TallGeese_previous_totalio_read)
# store values for next check
TallGeese_previous_date=$( echo $Out_buffer | awk '{print $1;}')
TallGeese_previous_totalip_in=$( echo $Out_buffer | awk '{print $2;}')
TallGeese_previous_totalip_out=$( echo $Out_buffer | awk '{print $3;}')
TallGeese_previous_totalio_write=$( echo $Out_buffer | awk '{print $4;}')
TallGeese_previous_totalio_read=$( echo $Out_buffer | awk '{print $5;}')
# log values
echo $Out_buffer | awk 'match($0,"Next"){print substr($0,RSTART+5)}' >> "./$TallGeese_repertory_name/Log.dat"
# plot
cd "$TallGeese_repertory_name"
gnuplot plotscript.gmp
cd ..
echo "Check OK, Sleep"
sleep 10s
done
==== Ploting results ====
The script to plot values is plotscript.gmp :
set terminal png size 642,462 small
set key autotitle columnheader
set timefmt "%Y-%d-%m-%H:%M"
set xdata time
set format x "%H:%M"
set grid
set output 'CPU.png'
plot 'Log.dat' using 1:2 w l linewidth 3 lc rgb "#f7d301"
set output 'Net.png'
plot 'Log.dat' using 1:3 w l linewidth 3 lc rgb "#f7d301", '' using 1:4 w l linewidth 3 lc rgb "#1cac77"
set output 'Memory.png'
plot 'Log.dat' using 1:7 w l linewidth 3 lc rgb "#f7d301", '' using 1:6 w l linewidth 3 lc rgb "#1f75fe", '' using 1:5 w l linewidth 3 lc rgb "#ff2d2e"
set style fill transparent solid 0.5 noborder
quit
And I first prepared the file log.dat in the directory of the server, by adding at top :
Date %CPU NetTrafic_in NetTrafic_out Memory_used Memory_cached Memory_free Swap_used IO_write IO_read
(Important, do not forget to pass line after the first one.)
This gives you png like that, that you can incorporate into an HTML display based system :
{{ :software:shell_scripts:cpu.png?500 |}}{{ :software:shell_scripts:memory.png?500 |}} {{ :software:shell_scripts:net.png?500 |}}