Хотите проверить, удалось ли команде перенаправить свой вывод на переменную
В настоящее время я пишу 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
Может кто-нибудь мне помочь?
Ответы
Ответ 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