Вернуть одно значение из функции сценария оболочки

Пример:

#!/bin/sh

a() {
R=f
ls -1 a*
[ "$?" == "1" ] && { R=t; }
echo $R
}

r=`a`
echo $r

$r содержит t или же f но и выход ls команда.

Я могу написать ls -1 a* >/dev/null 2>/dev/null, но если есть более сложный скрипт, который может привести к ошибкам.

Есть ли способ вернуть одно значение из a()?

4 ответа

Решение

Функция оболочки может возвращать числовое значение. Рассмотрим 0 и 1, а не "f" и "t"

#!/bin/sh

a() {
R=0
ls -1 a*
[ "$?" == "1" ] && { R=1; }
return $R
}

a
r=$?
echo $r

Это все равно будет записывать вывод из ls -1 a* которым вы, вероятно, все еще хотите избавиться, но ценность r будет либо 0, либо 1 и не будет включать вывод.

Другие примеры перенаправления вывода из строки или целого блока хороши, и, как другие предложили, вы должны узнать другие способы проверки условий (но я предполагал, что ls был своего рода произвольный пример)

Вы можете поместить перенаправление в список команд:

{
  command1
  command2
}> / dev / null

Если в какой-то момент в скрипте вы не хотите выводить из последующих команд, вы можете перенаправить вывод оболочки с помощью exec встроенная:

эхо интересное
exec >/dev/null
эхо скучно

Обратите внимание, что это продолжается до конца скрипта, а не только до конца функции. Это заботится о командах после интересной, но не раньше.

Есть способ отменить эффект exec /dev/null, используя манипуляции дескриптора файла. Я не обязательно рекомендую это, хотя, потому что это может быть сложно тренироваться на практике. Идея состоит в том, чтобы переместить все, что связано со стандартным выводом, в другой дескриптор, затем перенаправить стандартный вывод в другой файл и, наконец, переместить исходный стандартный вывод обратно в стандартный вывод.

{
  exec 3> & 1 # дублировать fd 3 до fd 1 (стандартный вывод)
  exec >/dev/null   # подключить стандартный вывод к / dev / null
  эхо скучно
  exec 1>&3         # подключить стандартный вывод обратно к тому, что было сохранено в FD 3
  эхо интересное
  exec >/dev/null # снова подключить стандартный вывод к / dev / null
  эхо скучнее
} 3>/dev/null       # В фигурном списке должен быть где-то подключен fd 3,
                    # хотя на самом деле ничего не будет записано в него.

Вам не нужно использовать ls проверить наличие файлов, начинающихся с a, Просто используйте оболочку

a() {
  shopt -s nullglob
  ret="f"
  for file in a*
  do   
    ret="t"
    break
  done
  echo "$ret"
}
a() { 
ls -1 a*  > /dev/null
[ "$?" == "0" ] && echo t  || echo f

} 

r=`a` 
echo $r 

Подумайте об использовании [ -f filename ] и других файловых тестов.

Другие вопросы по тегам