2013-02-21 15 views
20

Znam kilka bardzo prostych poleceń w Linuksie i próbuję napisać kilka skryptów. Napisałem funkcję, która ocenia sumę ostatnich 2 cyfr w pięciocyfrowym numerze. Funkcja powinna łączyć tę wypadkową sumę między dwie ostatnie cyfry i zwracać ją. Powodem, dla którego chcę zwrócić tę wartość, jest to, że będę używał tej wartości w innej funkcji.W bash, jak przechowywać zwracaną wartość w zmiennej?

Ex: jeśli mam 12345, wtedy moja funkcja obliczy 4 + 5 i powrócić 495.

#!/bin/bash 

set -x 
echo "enter: " 
     read input 

function password_formula 
{ 
     length=${#input} 
     last_two=${input:length-2:length} 
     first=`echo $last_two| sed -e 's/\(.\)/\1 /g'|awk '{print $2}'` 
     second=`echo $last_two| sed -e 's/\(.\)/\1 /g'|awk '{print $1}'` 
     let sum=$first+$second 
     sum_len=${#sum} 
     echo $second 
     echo $sum 

     if [ $sum -gt 9 ] 
     then 
       sum=${sum:1} 
     fi 

     value=$second$sum$first 
     return $value 
} 
result=$(password_formula) 
echo $result 

Próbuję echo i zobaczyć wynik, ale jestem coraz wyjścia, jak pokazano poniżej.

-bash-3.2$ ./file2.sh 
+++ password_formula 
+++ echo 'enter: ' 
+++ read input 
12385 
+++ length=8 
+++ last_two=85 
++++ echo 85 
++++ sed -e 's/\(.\)/\1 /g' 
++++ awk '{print $2}' 
+++ first=5 
++++ echo 85 
++++ sed -e 's/\(.\)/\1 /g' 
++++ awk '{print $1}' 
+++ second=8 
+++ let sum=5+8 
+++ sum_len=2 
+++ echo 5 
+++ echo 8 
+++ echo 13 
+++ '[' 13 -gt 9 ']' 
+++ sum=3 
+++ value=835 
+++ return 835 
++ result='enter: 
5 
8 
13' 
++ echo enter: 5 8 13 
enter: 5 8 13 

Próbowałem też wydrukować wynik:

password_formula 
RESULT=$? 
echo $RESULT 

Ale to daje jakąś nieznaną wartość:

++ RESULT=67 
++ echo 67 
67 

Jak mogę prawidłowo przechowywać prawidłową wartość i wydrukować (do podwójne sprawdzenie) na ekranie?

Z góry dziękuję.

+0

Użycie skrótów tutaj wydaje się nie na miejscu. Możesz zrobić: 'first = $ {last_two: 0: 1}' i 'second = $ {last_two: 1: 1}' lub 'first = $ {last_two%?}' I 'second = $ {last_two #?} ' –

+0

Instrukcja" return "jest myląco nazwana dla osób przyzwyczajonych do języków wysokiego poziomu - lepszą nazwą może być" exit_status ". Jeśli chcesz zwrócić wynik składający się z wartości ciągu lub wartości liczbowej> 255, to musi to być wykonane przez "echo" lub inny sposób wyprowadzania na standardowe wyjście. – MikeW

Odpowiedz

4

Zmiana ta linia:

return $value 

tak:

echo $value 

Następnie można go uchwycić to wyjście.

+0

Nie ma sensu, moja funkcja zwraca '0' lub' 1' * i * drukuje coś na standardowe wyjście. Potrzebuję tylko numeru. –

+0

@ TomášZato, to nie jest dla 0s lub 1s lub wydruków. Jeśli potrzebujesz numeru, po prostu wpisz numer. – perreal

+0

Nadal nie rozumiesz, prawda? Spróbuj trochę więcej: muszę * wydrukować dane * ** i ** * zwrócić liczbę *. Czasami mogę używać danych (używając notacji '$()') czasami potrzebuję sprawdzić wartość zwracaną. –

18

Wartość zwracana (zwana również kodem wyjścia) jest wartością z zakresu od 0 do 255 włącznie. Służy do wskazywania sukcesu lub porażki, a nie do zwracania informacji. Każda wartość spoza tego zakresu będzie opakowana.

Aby powrócić informacji, takich jak numer, użyj

echo "$value" 

Aby wydrukować dodatkowe informacje, które nie mają być zrobione, użyj

echo "my irrelevant info" >&2 

Wreszcie, aby go uchwycić, użyj tego, co zrobiłeś :

result=$(password_formula) 

innymi słowy:

echo "enter: " 
     read input 

password_formula() 
{ 
     length=${#input} 
     last_two=${input:length-2:length} 
     first=`echo $last_two| sed -e 's/\(.\)/\1 /g'|awk '{print $2}'` 
     second=`echo $last_two| sed -e 's/\(.\)/\1 /g'|awk '{print $1}'` 
     let sum=$first+$second 
     sum_len=${#sum} 
     echo $second >&2 
     echo $sum >&2 

     if [ $sum -gt 9 ] 
     then 
       sum=${sum:1} 
     fi 

     value=$second$sum$first 
     echo $value 
} 
result=$(password_formula) 
echo "The value is $result" 
+0

Problem polega na tym, że muszę używać standardowego stdout, a nie stderr. –

1

Jest to spowodowane instrukcjami echo. Możesz przełączyć echo na odbitki i wrócić z echo. Poniżej znajduje się

#!/bin/bash 

set -x 
echo "enter: " 
read input 

function password_formula 
{ 
     length=${#input} 
     last_two=${input:length-2:length} 
     first=`echo $last_two| sed -e 's/\(.\)/\1 /g'|awk '{print $2}'` 
     second=`echo $last_two| sed -e 's/\(.\)/\1 /g'|awk '{print $1}'` 
     let sum=$first+$second 
     sum_len=${#sum} 
     print $second 
     print $sum 

     if [ $sum -gt 9 ] 
     then 
      sum=${sum:1} 
     fi 

     value=$second$sum$first 
     echo $value 
} 
result=$(password_formula) 
echo $result 
+0

Bardzo dziękuję wszystkim za szczegółowe wyjaśnienia. Teraz działa. – itsh

+0

Pytanie dotyczy sposobu uzyskania ** wartości zwracanej **, a nie wartości "echo". –

3

Powyższa odpowiedź sugeruje zmianę funkcji na echo danych zamiast zwracania go, aby mógł zostać przechwycony.

Dla funkcji lub programu, że nie można zmienić, gdy wartość powrotna musi być zapisana do zmiennej (jak test/[, która zwraca wartość 0/1 sukces), echo $? w podstawiania poleceń:

# Test if we're remote. 
isRemote="$(test -z "$REMOTE_ADDR"; echo $?)" 
# Or: 
isRemote="$([ -z "$REMOTE_ADDR" ]; echo $?)" 

# Additionally you may want to reverse the 0 (success)/1 (error) values 
# for your own sanity, using arithmetic expansion: 
remoteAddrIsEmpty="$([ -z "$REMOTE_ADDR" ]; echo $((1-$?)))" 

Np

$ echo $REMOTE_ADDR 

$ test -z "$REMOTE_ADDR"; echo $? 
0 
$ REMOTE_ADDR=127.0.0.1 
$ test -z "$REMOTE_ADDR"; echo $? 
1 
$ retval="$(test -z "$REMOTE_ADDR"; echo $?)"; echo $retval 
1 
$ unset REMOTE_ADDR 
$ retval="$(test -z "$REMOTE_ADDR"; echo $?)"; echo $retval 
0 

Dla programu, który drukuje dane, ale także ma wartość zwracaną zostać zapisane, wartość zwracana będzie ujęte odrębnie od wyjścia:

# Two different files, 1 and 2. 
$ cat 1 
1 
$ cat 2 
2 
$ diffs="$(cmp 1 2)" 
$ haveDiffs=$? 
$ echo "Have differences? [$haveDiffs] Diffs: [$diffs]" 
Have differences? [1] Diffs: [1 2 differ: char 1, line 1] 
$ diffs="$(cmp 1 1)" 
$ haveDiffs=$? 
$ echo "Have differences? [$haveDiffs] Diffs: [$diffs]" 
Have differences? [0] Diffs: [] 

# Or again, if you just want a success variable, reverse with arithmetic expansion: 
$ cmp -s 1 2; filesAreIdentical=$((1-$?)) 
$ echo $filesAreIdentical 
0 
3

Najprostsza odpowiedź:

powrót kod z funkcji może być tylko wartością z zakresu od 0 do 255. Aby zapisać tę wartość w zmiennej trzeba zrobić tak jak w poniższym przykładzie:

#!/bin/bash 

function returnfunction { 
    # example value between 0-255 to be returned 
    return 23 
} 

# note that the value has to be stored immediately after the function call : 
returnfunction 
myreturnvalue=$? 

echo "myreturnvalue is "$myreturnvalue 
5

Łatwo trzeba echo wartości potrzebne do powrotu, a następnie uchwycić go jak poniżej

demofunc(){ 
    local variable="hellow" 
    echo $variable  
} 

val=$(demofunc) 
echo $val 
+1

To powinna być zaakceptowana odpowiedź. Obecna jest niekompletna i niepoprawna gramatyka. – Buffalo

+0

Zgadzam się. Ten jest najłatwiejszy w użyciu. –

+0

Jeśli dodasz 'echo 555' lub coś podobnego przed' echo $ variable', to połączy się z '$ variable' która jest zła – Groosha

0

Użyj specjalnej zmiennej bash "$?" tak:

function_output=${my_function} 
function_return_value=$? 
Powiązane problemy