Script v BASH

lukas016

Script v BASH
« kdy: 30. 12. 2011, 21:44:05 »
Dobry den.

Pred par dnami som sa zacal ucit bash. Ale ked som zacal pisat script tak som narazil na jeden problem s priradzovanim hodnot premenym. Ked preberam premenu zo vzdialeneho servera tak mi vzdy prida na konci premenej \r.
Hodnotu premenej prirazujem pomocou ssh:
PREMENA="$(ssh user@$ipservera :put '"$meno_$board.backup"')"
Premene pouzite za prikazom :put sa ziskavaju pomocou scriptu a vnutornych prikazov vzdialeneho servera na ktorom bezi Mikrotik.
Neskor potrebujem pomocou scp stiahnut subor ale kedze premena nadobudla aj text \r tak dostavam len odpoved, ze subor alebo priecinok nebol najdeny. Podla mna budem problem v samotnom ziskavani premenej kde pouzivam prikaz :put.

Ak by mi vedel niekto poradit bol by som velmi vdacny. Za odpovede vopred dakujem.


Kit

Re:Script v BASH
« Odpověď #1 kdy: 30. 12. 2011, 22:00:10 »
Předně jsou podivné ty vnější uvozovky. Ty tam vůbec nemusí být.

Vždycky se snažím vyhnout vnitřním proměnným v shellu a raději výstup příkazu rovnou zpracuji dalším příkazem pomocí roury. Většinou to jde. Co dál děláš s proměnnou $PREMENA ? Možná ji vůbec nepotřebuješ a její použití je na škodu.

Re:Script v BASH
« Odpověď #2 kdy: 30. 12. 2011, 22:11:46 »
Jestli ti jde jen o odstranění toho \r tak můžeš použít sed nebo tr, asi by šel i cut. Třeba sed "s/co chceš nahradit/čím chceš nahradit/g" , jinak zpetne lomitko se musi napsat zdvojene, myslim. Asi by šel i cut -d "\" -f 1 . Vysledek muze byt asi takto PREMENA=$(ssh user@$ipservera :put '"$meno_$board.backup"' |   cut -d "\" -f 1) . Svislá čára | je takzvaná roura, ta předá výstup dalšímu programu.

lukas016

Re:Script v BASH
« Odpověď #3 kdy: 30. 12. 2011, 22:31:06 »
Tu je zaklad scriptu :
#!/bin/bash
ipadresa="$(head -n 1 subor.txt)"
ssh user@$ipadresa :global identity [/system identity get name]
ssh user@$ipadresa :global board [/system resource get board-name]
ssh user@$ipadresa / system backup save name='"$identity_$board.backup"'
CELE="$(ssh user@$ipadresa :put '"$identity_$board.backup"')"
scp user@$ipadresa:$CELE /home/user/

Tie zatvorky su tam pouzite preto aby script pouzil vnutorne premene definovane na servery s mikrotikom lebo inak sa snazi pouzit premene definovane priamo v scripte.

mx1

Re:Script v BASH
« Odpověď #4 kdy: 31. 12. 2011, 02:04:14 »
Rozcvička, příklad dvouřádkového textu v proměnné.
~$ vysledek=$( echo -e 'Hello\nWorld' ) ; echo "$vysledek"
Hello
World

Totéž v ASCII, aby se nám lépe hledal zakopaný pes. Konce řádků jsou v UNIXu 0x0a ('\n'), ale jinde můžou být 0x0d 0x0a ('\r\n')
~$ vysledek=$( echo -e 'Hello\nWorld' ) ; echo "$vysledek" | hexcat
00000000 - 48 65 6c 6c  6f 0a 57 6f  72 6c 64 0a               Hello.World.

Prázdné řádky na konci mi někdo sežral. Asi bash. Je dobré to vědět (ale netrápit se tím).
~$ vysledek=$( echo -e 'Hello\nWorld' ) ; echo -n "$vysledek" | hexcat
00000000 - 48 65 6c 6c  6f 0a 57 6f  72 6c 64                  Hello.World

~$ vysledek=$( echo -e 'Hello\nWorld\n\n\n\n\n\n' ) ; echo -n "$vysledek" | hexcat
00000000 - 48 65 6c 6c  6f 0a 57 6f  72 6c 64                  Hello.World


Otázka: '\r'
~$ vysledek=$( echo -e 'Hello\r\nWorld\r\n' ) ; echo -n "$vysledek" | hexcat
00000000 - 48 65 6c 6c  6f 0d 0a 57  6f 72 6c 64  0d           Hello..World.

Odpověď 1 -- smazat hned u zdroje
~$ vysledek=$( echo -e 'Hello\r\nWorld\r\n' | tr -d '\r' ) ; echo -n "$vysledek" | hexcat
00000000 - 48 65 6c 6c  6f 0a 57 6f  72 6c 64                  Hello.World

Odpověď 2 -- smazat dodatečně
~$ mezivysledek=$( echo -e 'Hello\r\nWorld\r\n' ) ; vysledek=$( echo "$mezivysledek" | tr -d '\r' ) ; echo -n "$vysledek" | hexcat
00000000 - 48 65 6c 6c  6f 0a 57 6f  72 6c 64                  Hello.World


Síla příkazové řádky není jen v BASHi samotném, ale v té spoustě jednoduchých nástrojů,
tr 'aeiouy' 'iouyae' je jen jeden z mnoha. Pár dalších: man info less grep ps kill cat hexcat od fold head tail split wc md5sum sha2 sort uniq cut tr ls cp ln mkdir rm chown chmod df echo test true false tee basename uname date nice sleep seq gzip bzip2 tar diff find
Doporučuju info coreutils


lukas016

Re:Script v BASH
« Odpověď #5 kdy: 31. 12. 2011, 15:36:51 »
Velmi pekne dakujem tr mi pomohlo. Mohol by si mi poslat este prosim poslat stranku o tych prikazoch lebo ja som cerpal informacie len z www.linuxexpres.cz a pokusmi.

kklkj

Re:Script v BASH
« Odpověď #6 kdy: 31. 12. 2011, 22:34:11 »
V ZSH sa to da vyriesit takto. Malo by to byt rychlejsie ako vytvaranie dvoch procesov spojenych pipe-ou.

Kód: [Vybrat]
$ tst="Hello world\rLOL"
$ echo ${tst}
LOLlo world

$ autoload -U regexp-replace
$ regexp-replace tst '\\r' ' '
$ echo ${tst}
Hello world LOL


lukas016

Re:Script v BASH
« Odpověď #7 kdy: 01. 01. 2012, 03:22:28 »
TR vyriesilo moj problem bez problemov a dopisat par pismen nieje problem ale dik za ochotu.
Ale narazil som na dalsi problem ked som sa snazil program zacyklit tak prvy cyklus vykonalo dobre ale dalsi zacalo robit cudne veci.
Cely skript :
#!/bin/bash
for (( PORADIE=1 ; $PORADIE-3 ; PORADIE=$PORADIE+1 ))
do
IPADRESA="$(head -n $PORADIE seznam2.txt)"
ssh xxxxxx@$IPADRESA :global identity [/system identity get name]
ssh xxxxxx@$IPADRESA :global board [/system resource get board-name]
DOSKA="$(ssh xxxxx@$IPADRESA :put '$identity' | tr -d "\r")"
NAZOV="$(ssh xxxxx@$IPADRESA :put '$board' | tr -d "\r")"
CELE="$NAZOV"_"$DOSKA"
ssh lukas016_2@$IPADRESA / system backup save name=\"$CELE\"
CELE="$CELE".backup""
wget --ftp-user=xxxxxx --ftp-password=xxxxx ftp://$IPADRESA/$CELE
done

Chybne hlasenie :
http://imgupload.sk/viewer.php?file=01730107364355642760.png

Za pomoc vopred dakujem.

lukas016

Re:Script v BASH
« Odpověď #8 kdy: 01. 01. 2012, 16:12:29 »
Keby niekomu trebalo tak tato verzia by mala fungovat :
#!/bin/bash
for (( PORADIE=1 ; $PORADIE-3 ; PORADIE=$PORADIE+1 ))
do
c="$PORADIE"p""
IPADRESA="$(sed -n $c seznam2.txt)"
ssh xxxxxx@$IPADRESA :global identity [/system identity get name]
ssh xxxxxx@$IPADRESA :global board [/system resource get board-name]
DOSKA="$(ssh xxxxx@$IPADRESA :put '$identity' | tr -d "\r")"
NAZOV="$(ssh xxxxx@$IPADRESA :put '$board' | tr -d "\r")"
CELE="$NAZOV"_"$DOSKA"
ssh lukas016_2@$IPADRESA / system backup save name=\"$CELE\"
CELE="$CELE".backup""
scp xxxxx@IPADRESA:$CELE /home/xxxx/
done

Logik

  • *****
  • 1 022
    • Zobrazit profil
    • E-mail
Re:Script v BASH
« Odpověď #9 kdy: 01. 01. 2012, 20:38:16 »
Gratuluju k nalezení chyby. Pár poznámek:
Když někam vkládáš proměnou, dej ji do uvozovek, vyhneš se tím, že se ti rozexpanduje na víc argumentů. Např.
Kód: [Vybrat]
ssh xxxxxx@"$IPADRESA" .....

Pravděpodobně chceš zpracovat všechny řádky toho souboru, pak je jednodušší
Kód: [Vybrat]
while read IPADRESA
do
    ... tady něco dělám
done < seznam.txt
zpracuje to v cyklu soubore řádku po řádce

Když chceš někam vložit proměnou a je oko binec, dej jí do složenejch závorek, např.:
Kód: [Vybrat]
IPADRESA="`sed -n ${PORADIE}p seznam2.txt`"skript bude jasnější než když ten kus poskládáš vedle.

A nepoužívej nezabezpečené ftp a hesla ve skriptu, udělej si tam klíče a kopíruj to vždy pomocí scp, nebo pokud tam neběží scp, tak stačí i
Kód: [Vybrat]
cat <tenhle soubor chci zkopírovat> | ssh <na pocitac> 'cat >do souboru'
nebo to můžeš i prohnat gzipem, CPU stojí míň než konektivita (to už nechám na tebe).

Logik

  • *****
  • 1 022
    • Zobrazit profil
    • E-mail
Re:Script v BASH
« Odpověď #10 kdy: 01. 01. 2012, 22:10:09 »
Ještě k tomu zpracování řádek po řádku: chtělo by to také ty řádky zkontrolovat, zdali obsahují ip adresu (např. na konci může být jeden prázdný řádek apod.) Ale to snadno uděláš ifem s testem na regexp, např.:
Kód: [Vybrat]
if [[ $IPADRESA =~ \s*([0-9]{1,3}\.){3}[0-9]{1,3}\s*$ ]] ; then
   ....
fi;
PS: u regexp; v [[ ]] nepoužívej uvozovky, nepatřej tam.

lukas016

Re:Script v BASH
« Odpověď #11 kdy: 02. 01. 2012, 01:26:50 »
DIK pozriem sa na to lebo subor nebude mat len IP adresy a potom tu vlozim finalnu verziu lebo toto bol len zaklad

Logik

  • *****
  • 1 022
    • Zobrazit profil
    • E-mail
Re:Script v BASH
« Odpověď #12 kdy: 02. 01. 2012, 11:46:52 »
Pokud nebude mít jen ipadresy, tak tam zaveď něco jako sekce v ini souborech, na začátku dej testování,
zdali řádka není začátek nové sekce, jméno aktuální sekce si pamatuj v proměný a pak podle tý proměný
udělej rozskok pomocí case.
Pokud bys to dělal dle čísel řádek, pak Ti přibude jeden PC a musíš přečíslovávat celej skript, do konfiguráku nemůžeš
dát komentáře, jakékoli konfigurace s předem neznámým počtem voleb atd. atd.