BASH/Terminalas nulūžta

N
  • 31 Geg '13

http://www.zimagez.com/zimage/screensho ... 212656.php
(tik be '#') (situacija atkurta iš atminties, gali būti netikslumų nuotraukoj)

gaunu bandydamas nu'direktint vienos programos output'ą į stdout, o iš jo - į kintamąjį. Man tai pavyksta, bet kažkas čia sulūžta: ENTER terminale nebeduoda newline'o. Tarkim, veiksmas vyksta putty'je.
beje, ta programa, kurios išvestį gaudau, praktiškai visą išvestį pateikia į stderr (taip sukurta -- power broker).
Gal kas nujaučiat, KAS būtent čia nulūžta, kas būtent tai sukelia (spec. simbolis output'e/bug'as/kreivos rankos...)?

p.s. ką 'find / -name "programa" &>/dev/null' čia nutildo?

Nujaučiu, kad pirmas atsakęs bus Techtronic nagi, forumiečiai, pasistenkit, neužleiskit pirmos vietos jam!

T
Techtronic
Mindaugas N.
  • 1 Bir '13

Esi teisus, bet as neatsakysiu, tik duosiu paskaityti.
http://www.tldp.org/LDP/abs/html/io-redirection.html

N
  • 1 Bir '13

ABS pastaruoju metu sudomino ir vis karts nuo karto užmetu akį. Ačiū

Bet vis tiek nesupratau, kas „nulūžta“.. bandžiau savo netbuke išprovokuot panašų sutrikimą uždarinėdamas visus 3 deskriptorius, bet nieko... tik uždarius stderr gavau kažką į tą pusę (visiškai pastrigo terminalas) (kodėl?), bet neišprovokavau, kad tik dingtų newline'as pamygus ENTER...

G
  • 4 Bir '13

@netikras rašė:
p.s. ką 'find / -name "programa" &>/dev/null' čia nutildo?

&> /dev/null

reiškia tą patį kaip ir:

1> /dev/null 2>&1

Pirmas variantas - trumpesnė antrojo versija.

Jei nori išsaugoti programos išvestį į kinatamąjį:

kintamasis=$(programa)

Paprastai klaidų pranešimai nutylint nukreipiami į 'std out', t.y. ekraną (bent jau dabar neatsimenu pavyzdžio, kad būtų kitaip). Todėl nukreipimo operatoriai:

  • 1> (ekranas);
  • 2> (klaidų pranešimai);

paprastai naudojami tam, kad eliminuoti vieną iš jų. Sakykim, nenori matyti programos išvesties - nukreipi ją į /dev/null. Nori registruoti klaidų pranešimus - nukreipi juos į failą ir pan..

PAVYZDYS:

# mkdir -p ls-testas/testas1
# programa='ls -l ls-testas/'
# eval $programa
total 4
drwxr-xr-x 2 root root 4096 Jun  4 23:44 testas1
# programa='ls -l ls-testas/ ls-testas/testas2'
# eval $programa
ls: cannot access ls-testas/testas2: No such file or directory
ls-testas/:
total 4
drwxr-xr-x 2 root root 4096 Jun  4 23:44 testas1
# eval $programa 2> /dev/null
ls-testas/:
total 4
drwxr-xr-x 2 root root 4096 Jun  4 23:44 testas1
# eval $programa 1> /dev/null
ls: cannot access ls-testas/testas2: No such file or directory
# kintamasis=$(eval $programa 2> /dev/null)
# echo $kintamasis
ls-testas/: total 4 drwxr-xr-x 2 root root 4096 Jun 4 23:44 testas1
# echo "$kintamasis"
ls-testas/:
total 4
drwxr-xr-x 2 root root 4096 Jun  4 23:44 testas1

SPRENDIMAS:

  • Sukuriam aplanką: ls-testas, o jame kitą - testas1.
  • Apsirašom programą - ls -l ls-testas/
  • Paleidžiam programą per eval.
  • Apsirašom programą iš naujo, įtraukiam neegzistuojantį katalogą “testas2”.
  • Vėl paleidžiam programą ir matom, kad tiek stdout, tiek stderr atsidurė ekrane: atvaizduotas pirmojo katalogo turinys bei klaidos pranešimas, kad antrojo nėra.
  • Vėl paleidžiam programą, bet paslepiam stderr (2> /dev/null) (klaidos pranešimą).
  • Vėl paleidžiam programą, bet paslepiam stdout (1> /dev/null) (parodom tik klaidos pranešimą).
  • Apsirašom kintamąjį ir jame išsaugom programos išvestį paslėpdami stderr.
  • Atspausdinam kintamąjį vienu būdu.
  • Atspausdinam kintamąjį kitu būdu. Atkreipk dėmesį į dvigubas kabutes - jas naudodamas išsaugosi formatavimą.

Tikiuosi dabar aiškiau

Beje, jei domina Bash, norėčiau rekomenduoti knygą:
Pro Bash Programming: Scripting the GNU/Linux Shell

Sėkmės rašant Bash scenarijus!

N
  • 14 Bir '13

Ačiū už tikrai nemenką nepagailėto laiko kiekį
Šitai kaip ir žinojau jau. Nesu visai žalias BASH'e Tiesiog darbe yra įrankis, kuris elgiasi kiek kitaip, nei visos kitos mano iki šiol naudotos programos. Todėl teko artimiau susipažint su fd ir jų nukreipimais. Vis tiek jie man dar keistai skaitosi... kažkaip.. iš dešinės į kairę

Kaip bebūtų, mano naudojamas įrankis man reikalingą output'ą meta į STDERR (&2). Bandžiau tą išvestį pasigaut į kintamąjį (išsigrep'int reikalingą jo eilutę ir numest į kintamąjį), bet šis veiksmas man kažką 'sulaužo'. Kaip kad bandyta sumaketuot nuotraukoje, toks jausmas, kad toliau naudojantis terminalu TTY sesija praranda "\n" simbolį. T.y. normaliai terminalas atrodo taip:

Ghost-notebook$

tada pamygus kelis kartus ENTER turėtų būti:

Ghost-notebook$
Ghost-notebook$
Ghost-notebook$

tačiau yra:

Ghost-notebook$ Ghost-notebook$ Ghost-notebook$

Nežinau kaip aiškiau parodyt kažką mano bandymas stderr numest į kintamąjį sugadina. Niekaip neišrišu KĄ... (p.s. bandžiau komandą vykdyt ir be skliaustelių; tik paminiu, nes nuotraukoje parodyta su vidiniais skliausteliais).


Dabar užstrigau dar poroj vietų..

ssh -s $username@$hostname "bash -s" <<EOF
$commandline
EOF

ar va šitokį daiktą dar galima įmontuot į expect'ą, kad jis tikėtųsi "(yes/no)", "*ssword:" ir "COM:" ir įvestu atitinkamus BASH'o kintamuosius? Klausimas šiaip nekiltų, bet.. HEREDOC'as kelia abejonių.

--------kita vieta--------

Ar galima 'iš išorės' kaip nors matyti BASH skripto kintamuosius. Kitaip tariant, ar saugu jiems priskirti slaptažodžius? Neturi kiti vartotojai skripto veikimo metu galimybės kaip nors "nutycharint" mano passw?

N
  • 14 Bir '13

papildymas:

@netikras rašė:
T.y. normaliai terminalas atrodo taip:

Ghost-notebook$

tada pamygus kelis kartus ENTER turėtų būti:

Ghost-notebook$
Ghost-notebook$
Ghost-notebook$

tačiau yra:

Ghost-notebook$ Ghost-notebook$ Ghost-notebook$

dar vienas simptomas..
kai yra

Ghost-notebook$ Ghost-notebook$ Ghost-notebook$

nesimato ekrane, ką rašau.
pvz.: parašai: echo labas - nieko nesimato. pamygi ENTER - pasirašo 'labas' ekrane ir atsiranda newline'as:

Ghost-notebook$ Ghost-notebook$ Ghost-notebook$ labas
                                                                                               Ghost-notebook$ Ghost-notebook$
G
  • 16 Bir '13

Sveikas,

Sunku patarti, kai visai neparodai išvesties kodo..

Kaip suprantu, pas tave dedasi kažkas tokio, kaip dubliuojant vieną specialų kintamąjį:

bak=$PS1
PS1=$PS1$bak
PS1=$PS1$bak
PS1=$PS1$bak

Nuo to ir reikia pradėti ieškoti. Tačiau nematydamas kodo pasakyti kur tu susimovei negaliu

T
Techtronic
Mindaugas N.
  • 16 Bir '13

Ar esi tikras, kad klaidos nera ~/profile arba ~/.bashrc, paziurek $PROMPT (PS1|2|3). Naudok printf jeigu reikia.

ar va šitokį daiktą dar galima įmontuot į expect'ą, kad jis tikėtųsi "(yes/no)"> @netikras rašė:

ar va šitokį daiktą dar galima įmontuot į expect'ą, kad jis tikėtųsi "(yes/no)", "*ssword:" ir "COM:" ir įvestu atitinkamus BASH'o kintamuosius? Klausimas šiaip nekiltų, bet.. HEREDOC'as kelia abejonių.

Gali meginti if $(tavo komanda &>/dev/null);.

@netikras rašė:
Ar galima 'iš išorės' kaip nors matyti BASH skripto kintamuosius. Kitaip tariant, ar saugu jiems priskirti slaptažodžius? Neturi kiti vartotojai skripto veikimo metu galimybės kaip nors "nutycharint" mano passw?

Bash nera programavimo kalba, ir jeigu kas turi teise tavo skripta read, tai aisku gali paziureti kas jame. arba

└% /bin/bash -x test.sh
+ PASSWORD=cool
N
  • 21 Bir '13

Ghost, programa, kuri spjaudosi, yra PowerBroker modulis: pbrun. Neturiu po ranka dabar jo source kodo o į terminalą vedu, tarkim:

var=$(pbrun puc $host uptime 2>&1)

=======================
Tech,

mano $HOME yra tuščias, ~/.bashrc pats rašiausi.. bet ir tai tik kelias eilutes -- nėra kur suklyst kitiems vartotojams - tokios pačios problemos su output'u..

dėl kintamųjų.. taip, suprantu, kad source gali matyti bet kas, kas turi ro/rw teises. Bet ar įmanoma rasti jau paleisto skripto kintamuosius? nėra jie kur nors saugomi /proc/ kataloge ar pan.?
pvz.:
read -p "Enter Password: " passw
curl -s $username:$passw@$host/data/main.php

ar įmanoma pašaliniams sužinoti, kokią reikšmę saugo $passw kintamasis?
Būtų programavimo kalba (cpp/java), būtų ramu. Bet dabar kažkaip prisibijau taip drąsiai slaptažodžius į kintamuosius kišt...

T
Techtronic
Mindaugas N.
  • 22 Bir '13

netikras, pagalvok apie /proc/[\d]+/*. Aisku taip tik tada kai turi teise read procesa paleista is to user.
Del cpp/java tas pats, tai nera labai sudetinga su gdb istraukti tai kas yra atminti.

Tokiam kaip zsh gali unset tai ka esi nustates, bet dar nera teke tikrinti ar tikrai jau unset veikia taip kaip turetu.

Va turiu tau ideja, gal kiek saugesnis budas

#! /bin/bash

HTPASSWD=/var/www/.htpasswd

die () { echo "$*" >&2 ; exit 1 ; }

read -p 'Enter user name: ' USER
read -s -p 'Old password: ' OLDPW ; echo
read -s -p 'New password: ' NEWPW0 ; echo
read -s -p 'Re-type new password: ' NEWPW1 ; echo

if LINE=$(grep ^"$USER": "$HTPASSWD")
then
    echo "$LINE" | sed 's/.*:\(..\)\(.\+\)/\1 \2/' | { 
        read SALT CRYPT
        if [[ "$SALT$CRYPT" = $(echo "$OLDPW" | mkpasswd -sS "$SALT") ]] ; then
            if [ "$NEWPW0" != "$NEWPW1" ] ; then
                die "Password verification error!"
            fi
            PWS=$(grep -v ^"$USER:" "$HTPASSWD")
            {
                echo "$PWS"
                echo -n "$USER:"
                echo "$NEWPW0" | mkpasswd -s
            } > "$HTPASSWD"
            echo "Updating password for user $USER."
        else
            die "Password verification error!"
        fi
    }
else
    die "Password verification error!"
fi