Подтвердить что ты не робот

Хотите проверить, удалось ли команде перенаправить свой вывод на переменную

В настоящее время я пишу bash script, который загружает видеофайлы до YouTube, используя GoogleCL.

Как я делаю эту загрузку в цикле (потому что может быть несколько видеофайлов), я хотел бы проверить, был ли каждый файл загружен успешно, прежде чем я загружу следующий.

Команда google youtube post --access unlisted --category Tech $f (где $f представляет файл) выводит строку, которая сообщает мне, была ли загрузка успешной или нет.

Но я не знаю, как перенаправить эту "возвращаемую строку" в переменную, чтобы проверить успешность.

Что я имею:

for f in ./*.ogv ./*.mov ./*.mp4
do
    if [[ '*' != ${f:2:1} ]]
    then
        echo "Uploading video file $f"

        # How to put the return value of the following command into a variable?
        google youtube post --access unlisted --category Tech $f > /dev/null

        # Now I assume that the output of the command above is available in the variable RETURNVALUE
        if [[ $RETURNVALUE == *uploaded* ]]
        then
            echo "Upload successful."
        else
            echo "Upload failed."
        fi
    fi
done

Может кто-нибудь мне помочь?

4b9b3361

Ответ 1

Я предполагаю, что вы также можете зависеть от кода ошибки от команды google (я предполагаю, что она возвращает ошибку, если она не была загружена, но вам, вероятно, следует дважды проверить это).

for f in ./*.ogv ./*.mov ./*.mp4; do
  if [[ '*' != ${f:2:1} ]]; then

    echo "Uploading video file $f"
    if google youtube post --access unlisted --category Tech "$f" > /dev/null
    then
      echo "Upload successful."
    else
      echo "Upload failed."
    fi

  fi
done

Общепринятое заблуждение состоит в том, что если требуется выражение в скобках для оценки, это неверно, если всегда берет команду и проверяет статус ошибки; обычно эта команда [, которая является псевдонимом для test, который вычисляет выражение. (И да, я был бы удивлен, если бы не оптимизированный ярлык, чтобы ускорить его работу внутри bash, но концептуально это все еще верно).

Захват вывода выполняется с помощью обратных тактов

result=`command argument a b c`

или используя $()

result=$(command argument a b c)

но, вероятно, лучше использовать код ошибки в этом случае.

РЕДАКТИРОВАТЬ: У вас есть забавная вещь в вашей функции. Сначала я не заметил, но ее можно избежать, если вы включите опцию оболочки nullglob (это приведет к тому, что ./*.mov будет раскрываться до пустой строки, если нет файлы). Кроме того, укажите, что $f или он сломается, если ваши имена файлов содержат пробелы

shopt -s nullglob
for f in ./*.ogv ./*.mov ./*.mp4; do
  echo "Uploading video file $f"
  if google youtube post --access unlisted --category Tech "$f" > /dev/null
  then
    echo "Upload successful."
  else
    echo "Upload failed."
  fi
done

НТН.

Ответ 2

Я бы назвал это, The command ... outputs a string. "Возврат" - это ключевое слово, а возвращаемое значение - это число, где 0 означает успех соглашения (0 ошибок), а другое значение указывает код ошибки.

Вы получаете результат:

result=$(google youtube post --access unlisted --category Tech $f)

но часто видит низшее решение:

result=`cmd param1 param2`

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

От 'man bash':

Возвращаемое значение простой команды это его статус выхода, или 128 + n, если команда завершается сигналом n.

и

return [n]
  Вызывает функцию для выхода с указанным возвращаемым значением по n. Если n опущено, возврат статус - это последний               команда, выполняемая в теле функции. Если используется вне функции, но во время выполнения script. (источник)               команда, это заставляет оболочку прекратить выполнение этого scriptи вернуть либо n, либо статус выхода последней команды               выполненный в script в качестве статуса выхода script. Если используется вне функции а не во время выполнения               script by., статус возврата - false. Любая команда связанных с ловушкой RETURN выполнено до выполнения               возобновляется после функции или script.

Код возвращаемого значения/выхода последней команды получается через $?.

Ключевое слово для значения, которое вы имели в виду, означает подстановка команды. Опять 'man bash':

Замена команды
  Подстановка команд позволяет выводить команду на замену имя команды. Существуют две формы:

          $(command)
   or
          `command`

Bash выполняет расширение, выполняя команду и заменяя подстановку команд стандартным вывода команды, с удалением любых завершающих строк. Встроенные новые строки не удаляются, но они могут быть удаляется при разбиении слова.        Командная подстановка $(файл cat) может быть заменена на эквивалентный, но быстрее $(< файл).

   When  the old-style backquote form of substitution is used,

обратная косая черта сохраняет свое буквальное значение за исключением случаев, когда следует $, `,        или. Первый backquote, которому не предшествует обратная косая черта, завершает подстановка команд. При использовании $(командная) форма,        все символы между круглыми скобками составляют команду; никто обрабатываются специально.

   Command substitutions may be nested.  To nest when using the

обратная форма, избежать внутренней backquotes с обратной косой чертой.

Если подстановка появляется в двойных кавычках, разбиение слов и расширение пути не выполненных по результатам.

Ответ 3

Используйте $()

variable=$(google youtube post --access unlisted --category Tech $f )

Ответ 4

Если вы все еще получаете вывод после > /dev/null, то он выходит на stderr, поэтому стандартные обратные ссылки или $() не будут работать.

Во-первых, посмотрите, показывает ли код возврата проблему: Изучите $? после успеха и неудачи.

Если окажется, что код возврата не является достаточным, вы можете перенаправить вывод:

RETURNVALUE=$(google youtube post --access unlisted --category Tech $f 2>&1 >/dev/null)

2>&1 помещает stderr в stdout fd, прежде чем перенаправить stdout на ничего.

Ответ 5

Вы можете назначить его переменной с помощью обратных ссылок:

CONTENT=`google youtube post --access unlisted --category Tech $f > /dev/null`

Ответ 6

Пример для доступа к YouTube

rm ~/temp/youtube_top_title1.txt
rm ~/temp/youtube_top1.txt
curl  "http://www.youtube.com/"|\
grep -o 'watch[^"]*'|\
sort -n|\
uniq -c|\
awk '{if ($1!="1") print $2}'|\
while read i ; do\
    page_youtube=`curl -s  "http://www.youtube.com/${i}"`;\
    echo `echo -e "$page_youtube" |awk '{if ($1 ~ "") start=1; if ($1 ~ "") start=0; if (start == 1) print $0 }'|grep -v ''` >> ~/temp/youtube_top_title1.txt
    url_current=$(echo -e "$page_youtube"|\
    grep -o "url=[^,]*,"|\
    sed 's/url=//g;s/,//g'|\
    php -r '$f=fopen("php://stdin","r");while (FALSE!==($line=fgets($f))) echo urldecode($line);'|\
    awk '{print $1}'|\
    sed 's/;$//g'|\
    sed 's/\\u.*//g'|\
    tail -2|\
    head -1)
    echo "$url_current" >> ~/temp/youtube_top1.txt
done 

Ответ 7

Ответ на вопрос заключается в использовании команды read.

Уверен, что все эти другие ответы показывают, как не делать то, что задал ОП, но это действительно заманивает всех нас, которые искали вопрос ОП.

Отказ от ответственности: Это дублированный ответ

Вот как вы это делаете...

Команда:

# I would usually do this on one line, but for readability...
series | of | commands \
| \
(
  read string;
  mystic_command --opt "$string" /path/to/file
) \
| \
handle_mystified_file

Вот что он делает и почему это важно:

  • Предположим, что series | of | commands - очень сложная серия команд с каналами.
  • mystic_command может принимать stdin как файл, но не параметр arg, поэтому он должен входить как переменная **
  • read принимает stdin и помещает его в переменную $string
  • Ввод read и mystic_command в "подклассу" через скобки не требуется, но заставляет его течь как непрерывный канал, как если бы 2 команды, где в отдельном файле script.

** Всегда есть альтернатива, и в этом случае альтернатива уродлива и нечитаема:

mystic_command --opt "$(series | of | commands)" /path/to/file | handle_mystified_file