web-dev-qa-db-ja.com

出力を変数にリダイレクトして、コマンドが成功したかどうかを確認したい

私は現在、 GoogleCL を使用してビデオファイルをYouTubeにロードするbashスクリプトを書いています。

私はこのアップロードをループで行っているので(複数のビデオファイルが存在する可能性があるため)、次のファイルをアップロードする前に、各ファイルが正常にアップロードされたかどうかを確認したいと思います。

コマンド 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

誰かが私を助けてくれますか?

23
Patrick

私の推測では、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)
_

ただし、この場合はエラーコードを使用する方が良いでしょう。

編集: あなたはあなたの関数に面白いifの事があります..最初は気づきませんでしたが、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
_

HTH。

21
falstro

The command ... outputs a string。 'Return'はキーワードであり、戻り値は数値です。0は通常、成功(0エラー)を意味し、別の値はエラーを示しますコード。

次の方法で出力を取得します。

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

しかし、しばしば劣った解決策が見られます:

result=`cmd param1 param2`

劣っているのは、バッククォートが(フォントによっては)アポストロフィと混同されやすく、ネストが難しいためです。使用しないでください。

「man bash」から:

単純なコマンドの戻り値はその終了ステータス、またはコマンドがシグナルnで終了した場合は128 + nです。

そして:

戻る[n]
nで指定された戻り値で関数を終了させます。 nを省略すると、戻りステータスは関数本体で実行された最後のコマンドのステータスになります。関数の外で使用する場合、ただしによるスクリプトの実行中。 (ソース)コマンドの場合、シェルはそのスクリプトの実行を停止し、nまたはスクリプト内で実行された最後のコマンドの終了ステータスをスクリプトの終了ステータスとして返します。関数の外で使用し、。によるスクリプトの実行中に使用しない場合、戻りステータスはfalseです。 RETURNトラップに関連付けられているコマンドは、関数またはスクリプトの後で実行が再開される前に実行されます。

最後のコマンドの戻り値/終了コードは、$?を通じて取得されます。

意味のキーワードはコマンド置換です。もう一度 'man bash':

コマンド置換
コマンド置換により、コマンドの出力でコマンド名を置き換えることができます。 2つの形式があります。

          $(command)
   or
          `command`

Bashは、コマンドを実行し、コマンド置換をコマンドの標準出力に置き換え、末尾の改行を削除して、展開を実行します。埋め込まれた改行は削除されませんが、Wordの分割中に削除される場合があります。コマンド置換$(cat file)は、同等の高速な$(<file)で置き換えることができます。

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

バックスラッシュは、$、 `、またはが続く場合を除いて、文字どおりの意味を保持します。バックスラッシュが前に付いていない最初のバッククォートは、コマンド置換を終了します。 $(command)形式を使用する場合、括弧内のすべての文字がコマンドを構成します。特別に扱われるものはありません。

   Command substitutions may be nested.  To nest when using the

バッククォートされたフォーム、バックスラッシュで内側のバッククォートをエスケープします。

置換が二重引用符で囲まれている場合、結果に対してWordの分割とパス名の展開は行われません。

4
user unknown

$()を使用します

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

_> /dev/null_の後に出力を取得している場合、それはstderrで出力されるため、標準のバックティックまたは$()は機能しません。

まず、戻りコードが問題を示しているかどうかを確認します。$を調べますか?成功と失敗の後。

戻りコードが十分でないことが判明した場合は、出力をリダイレクトできます。

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

_2>&1_は、stdoutを何にもリダイレクトしない前に、stderrをstdout fdに配置します。

2
Douglas Leeder

バッククォートを使用して変数に割り当てることができます。

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

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 " )$ 2} '|\
を読みながら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 
完了
0
lamasnik

質問に対する答えは、readコマンドを使用することです。

確かに、これらの他のすべての回答は、OPが要求したことを行わない方法を示していますが、それはOPの質問を検索した残りの私たちを本当に台無しにします。

免責事項: これは重複した回答です

これがあなたのやり方です...

コマンド:

# 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

これが何をしているのか、なぜそれが重要なのかを示します。

  1. series | of | commandsが非常に複雑な一連のパイプされたコマンドであるとしましょう。
  2. mystic_command is stdin as the file、butnot the option argしたがってそれ変数として**
  3. readはstdinを受け取り、変数$stringに配置します
  4. readmystic_commandを括弧で「サブシェル」に入れる必要はありませんが、2つのコマンドが別のスクリプトファイルにあるかのように、連続したパイプのように流れます。

**代替手段は常にあり、この場合、代替手段は醜く、判読できません。

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