Want to check whether a command succeeded by redirecting its output to a variable

只谈情不闲聊 提交于 2019-12-03 09:41:07

My guess is that you could depend on the error code from the google command as well (I'm assuming it returns error if it failed to upload, but you should probably double check this).

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

A common misconception is that if wants a bracketed expression to evaluate, this is not true, if always takes a command and checks the error status; usually this command is [ which is an alias for test, which evaluates the expression. (And yes, I'd be surprised if there isn't an optimized shortcut to make it go faster inside bash, but conceptually it's still true).

Capturing output is done via backticks, like so

result=`command argument a b c`

or using $()

result=$(command argument a b c)

but it's probably better to use the error code in this case.

EDIT: You have a funny if thing in your function.. I didn't notice at first, but it can be avoided if you enable nullglob shell option (this will make ./*.mov to expand to the empty string, if there are no files). Also, quote that $f or it'll break if your file names contain spaces

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.

I would call it, The command ... outputs a string. 'Return' is a keyword, and the return value is a number, where 0 means by convention success (0 errors) and a different value indicates an error code.

You grab the output by:

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

but will often see the inferior solution:

result=`cmd param1 param2`

inferior, because backticks are easily confused with apostrophes (depending on the font) and hard to nest, so don't use them.

From 'man bash':

The return value of a simple command is its exit status, or 128+n if the command is terminated by signal n.

and:

return [n]
Causes a function to exit with the return value specified by n. If n is omitted, the return status is that of the last command executed in the function body. If used outside a function, but during execution of a script by the . (source) command, it causes the shell to stop executing that script and return either n or the exit status of the last command executed within the script as the exit status of the script. If used outside a function and not during execution of a script by ., the return status is false. Any command associated with the RETURN trap is executed before execution resumes after the function or script.

The return value/exit code of the last command is gained through $?.

The keyword for the meaning you meant is command substitution. Again 'man bash':

Command Substitution
Command substitution allows the output of a command to replace the command name. There are two forms:

          $(command)
   or
          `command`

Bash performs the expansion by executing command and replacing the command substitution with the standard output of the command, with any trailing newlines deleted. Embedded newlines are not deleted, but they may be removed during word splitting. The command substitution $(cat file) can be replaced by the equivalent but faster $(< file).

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

backslash retains its literal meaning except when followed by $, `, or . The first backquote not preceded by a backslash terminates the command substitution. When using the $(command) form, all characters between the parentheses make up the command; none are treated specially.

   Command substitutions may be nested.  To nest when using the

backquoted form, escape the inner backquotes with backslashes.

If the substitution appears within double quotes, word splitting and pathname expansion are not performed on the results.

If you are still getting output after > /dev/null then it's coming out on stderr, so standard backticks or $() won't work.

First, see if the return code indicates a problem: Examine $? after success and failure.

If it turns out the return code isn't sufficent, you can redirect the output:

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

2>&1 puts stderr on the stdout fd, before you redirect stdout to nothing.

Use $()

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

You can assign it to a variable by using backticks:

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

Example for access 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 
Bruno Bronosky

The answer to the question is to use the read command.

Sure all these other answers show ways to not do what the OP asked, but that really screws up the rest of us who searched for the OP's question.

Disclaimer: This is a duplicate answer

Here is how you do it...

Command:

# 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

Here is what it is doing and why it is important:

  1. Let's pretend that the series | of | commands is a very complicated series of piped commands.
  2. mystic_command is could accept stdin as the file, but not the option arg therefore it must come in as a variable**
  3. read takes stdin and places it into the variable $string
  4. Putting the read and the mystic_command into a "sub shell" via parenthesis is not necessary but makes it flow like a continuous pipe as if the 2 commands where in a separate script file.

** There is always an alternative, and in this case the alternative is ugly and unreadable:

mystic_command --opt "$(series | of | commands)" /path/to/file | handle_mystified_file
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!