Egy egyszerű BASH kérdés

Kedves Fórumtársak!

A következőről lenne szó:
Adott egy shell szkript. Azt lehet tudni, hogy a 10 és afeletti argumentumokat a ${szám} formában lehet elérni.
Én ezeket szeretném egy cikluson belül egy futóindex-szel egyenként elérni, és manipulálgatni. Azoban itt jön a trükkös része a dolognak. Hogyan is kellene ezt?

Az alábbi a kód:


#!/bin/bash

for i in `seq 1 $#`; do
    echo -e ${$i}
done

A probléma abban rejlik, hogy a kapcsos zárójelen belül gondja van a bash-nek a $-ral. Ha a kifejezés elé teszem, akkor pedig $$ lesz, ami a szkript pidje. Ha escape-elem az első $-t, akkor sem működik rendesen, úgyhogy kicsit talácstalan vagyok. Ezért fordulok hozzátok. Hogyan kellene ezt?
for i in "$@"-et nem akarok, mert az megkeveri a paramétereket, ha valamelyikben szóköz van.
Előre is köszönöm a válaszokat.

Üdv:
János

Hozzászólások

Nem értem a kérdést. Mit jelent az, hogy a "$@" megkeveri a paramétereket? Az alábbi nem lenne jó?


#!/bin/bash

for i in "$@"; do
  echo "$i"
done

$ ./test.sh 1 '2 3' 4
1
2 3
4

Valóban. Nálad a pont, nem rontja el.
Ellenben nekem arra kellene, hogy a seq-nél található 1-est 3-ra módosíva csak a 3-dik és amögötti argumentumokkal foglalkozzon.
Viszont nem akarnék beletenni egy if-et, csak ezért. Ezért nem szívlelem a $@-es megoldást.
__________________________________________________________
Az életben csak egy dolog a szép, de az épp nem jut eszembe.

Slackware Linux 12.1 | 2.6.26.7-janos

> Ha escape-elem az első $-t, akkor sem működik rendesen

igy: \${$i} ?

echo -e ${!i}

A felkiáltójel csinál indirekciót: az i-ben lévő változó értékét még egyszer mint változónevet értelmezi és újra kiértékeli.

> a=b
> b=c
> echo ${!a}
c

Ilyenkor össze kell állítani egy változóban magát a parancssort úgy, hogy ne zavarodjon meg tőle a bash, aztán eval segítségével végrehajtani:


#!/bin/bash

for i in `seq 1 $#`
do
  parancs='echo -e ${'$i'}'
  eval $parancs
done

---
Science for fun...

Újabb kérdésem támadt:
Ez miért nem működik?


echo "janos:12512:1000" | IFS=':' read a b c && echo a $a $b $c

Pusztán azért nem, mert a read egy beépített bash parancs, vagy valami másért?
A cucc tökéletesen megy, ha egy fájlt irányítok bele kacsacsőrrel, de ha |-al küldenöm neki a sorokat, akkor azt valamiért nem komálja.
__________________________________________________________
Az életben csak egy dolog a szép, de az épp nem jut eszembe.

Slackware Linux 12.1 | 2.6.26.7-janos

Hm. Ez érdekes.
Pont ez lenne a kívánt állapot, ellenben nekem csak az a-t írja ki. :S
__________________________________________________________
Az életben csak egy dolog a szép, de az épp nem jut eszembe.

Slackware Linux 12.1 | 2.6.26.7-janos

IFS=':' read a b c < <(echo "janos:12512:1000") && echo a $a $b $c

man bash -> process substitution

A "read" nem állhat pipe jobb oldalán, mert akkor számára technikailag külön subshellt indít a bash, amelyik beolvassa az értéket, majd rögtön ki is lép (tehát elfelejti), nekünk az kell, hogy ez a shell futtassa a read-et.

kezdem utálni a bash-t.
promtból működik, de szkriptben nem tetszik neki:


../Desktop/reown.sh: line 34: syntax error near unexpected token `<'
../Desktop/reown.sh: line 34: `         IFS=':' read scratch UFROM UTO < <(echo "janos:12512:1000")'

A szkript maga itt.
__________________________________________________________
Az életben csak egy dolog a szép, de az épp nem jut eszembe.

Slackware Linux 12.1 | 2.6.26.7-janos

sajna nekem még így szóköz nélkül sem megy :S


../Desktop/reown.sh: line 34: syntax error near unexpected token `('
../Desktop/reown.sh: line 34: `         IFS=':' read scratch UFROM UTO << (echo "$i")'

Most épp ezt bújom, hátha segít.
__________________________________________________________
Az életben csak egy dolog a szép, de az épp nem jut eszembe.

Slackware Linux 12.1 | 2.6.26.7-janos

Ahogy Egmont is rámutatott, az a probléma, hogy a read nem a saját bemenetéről olvas, hanem az őt futtató programéról. Mivel a függvény önálló héjban fut, adódik a következő körülményes (:-)) megoldás:


#!/bin/bash
olvas()
{
  IFS=':'
  read a b c
  echo $a $b $c
}

echo 'janos:12512:1000' | olvas

---
Science for fun...

érdekesen működnek itt a dolgok, de sikerült kierőszakolnom valami működőképeset:


#!/bin/bash

A=5 B=4 C=3 cat <<%%
-------------------------------------
(echo $1)
$A
$B $C
(echo This is line 2% of the message.)
This is the last line of the message.
-------------------------------------
%%

IFS=':' I=janos:12512:1000 read scratch UFROM UTO <<%%
$I
%%
echo $scratch $UFROM $UTO

Érdekes módon a változókat amiket használok a here-documentekben, azokat a paracs kedző sorában kell elhelyezni, különben a változók nem lesznek elérhetők.

Szerk: A kész szkript itt érhető el.
__________________________________________________________
Az életben csak egy dolog a szép, de az épp nem jut eszembe.

Slackware Linux 12.1 | 2.6.26.7-janos

Harmadik kérdés:
Ez a parancs miért nem változtatja meg a jelenlegi könyvtárszint alatt található symlinkek uid-jét?
[code]
find . -uid 12512 -exec chown 1000 '{}' \;
[code]
__________________________________________________________
Az életben csak egy dolog a szép, de az épp nem jut eszembe.

Slackware Linux 12.1 | 2.6.26.7-janos

köszi az infót.
csak furcsállom, mert mikor

chown usernév . -R

-rel eredetileg lecseréltem a fájlok tulaját, akkor megváltozott a symlinkek tulaja is...
__________________________________________________________
Az életben csak egy dolog a szép, de az épp nem jut eszembe.

Slackware Linux 12.1 | 2.6.26.7-janos