Nowski
Nowski

Reputation: 183

How to call a python script from bash with arguments?

I am going round and round in circles here and there is probably a very simple answer. I have a bash script that loops around video files in a thumbdrive and if it finds the .mp4 extension, it will upload to youtube using Youtube's python example - which works from the command line.

I'm having trouble passing the arguments to the python script call in the bash script:

cd /home/pi/Documents
echo $PWD
for _file in  /media/pi/*/*.mp4; do
     clean=$(echo $_file|wc -m)
     if [ $clean -gt 15 ]; then
           did=$(grep "$_file" /home/pi/Documents/uploaded_videos.txt | wc -l)
          if [ $did = 0 ]; then
               #Edit this to your liking
               #echo "now uploading $_file"
               args="--file=\"${_file}\" –-title=\"${_file}\" –-description=\"show 2018\" -–keywords=\"2018,show, Winter,show 2018,\" -–category=\"28\" -–privacyStatus=\"private\""
               python yt_up.py  "$args"
              echo $_file uploaded to youtube via google developer api | logger
               echo $_file >> /home/pi/Documents/uploaded_videos.txt
         fi
     fi
done

But the arguments are not recognised by the yt_up.py script. I've tried various combinations of quotes but I just can't get it to work.

I can pass one argument to the script:

python yt_up.py --file="$_file" works, but adding additional arguments were not recognised.

Upvotes: 0

Views: 9535

Answers (3)

sahaquiel
sahaquiel

Reputation: 1838

Your args variable for python is a large sys.argv[1], so may be you have troubles because of it.

Rewrite shell like this:

cd /home/pi/Documents
echo $PWD
for _file in  /media/pi/*/*.mp4; do
     clean=$(echo $_file|wc -m)
     if [ $clean -gt 15 ]; then
          did=$(grep "$_file" /home/pi/Documents/uploaded_videos.txt | wc -l)
          if [ $did = 0 ]; then
               #Edit this to your liking
               #echo "now uploading $_file"
               args=( $(echo "--file=\"${_file}\" –-title=\"${_file}\" –-description=\"show 2018\" -–keywords=\"2018,show, Winter,show 2018,\" -–category=\"28\" -–privacyStatus=\"private\"") )
               python yt_up.py  "${args[@]}"
               echo $_file uploaded to youtube via google developer api | logger
               echo $_file >> /home/pi/Documents/uploaded_videos.txt
          fi
     fi
done

Now args is array, and each it's element will be read by python as separated sys.argv[i] element.

Upvotes: 0

gniourf_gniourf
gniourf_gniourf

Reputation: 46813

Lots of antipatterns and misconceptions in your current code!

cd /home/pi/Documents

For best practice you should test whether this succeeded. Probably not a problem currently, but it doesn't hurt to do so.

echo $PWD

Missing quotes here, but that's not fatal.

for _file in  /media/pi/*/*.mp4; do
     clean=$(echo $_file|wc -m)

That's not how to count the number of characters in a string. You should use clean=${#_file} instead.

     if [ $clean -gt 15 ]; then

Here I guess you want to know whether the glob matched anything. That's not how to proceed. You either want to use the shopt -s nullglob option of Bash, or use if [ -e "$_file" ]; then to check whether the glob matched an actual file.

           did=$(grep "$_file" /home/pi/Documents/uploaded_videos.txt | wc -l)
          if [ $did = 0 ]; then

That's how you check whether a file doesn't contains a string. Use if ! grep -q "$_file" /home/pi/Documents/uploaded_videos.txt; then instead.

               #Edit this to your liking
               #echo "now uploading $_file"
               args="--file=\"${_file}\" –-title=\"${_file}\" –-description=\"show 2018\" -–keywords=\"2018,show, Winter,show 2018,\" -–category=\"28\" -–privacyStatus=\"private\""

Here you have misconceptions about how the shell reads a command. Quote removal is performed before variable expansion, so your quotes are wrong. Typically you want to use an array! that's what Bash arrays are for! Also note that you have some weird hyphens here.

               python yt_up.py  "$args"
              echo $_file uploaded to youtube via google developer api | logger
               echo $_file >> /home/pi/Documents/uploaded_videos.txt
         fi
     fi
done

Here's a possibility to fix your mistakes (and hopefully make it work):

#!/bin/bash

# We define a variable with the path to the uploaded_videos.txt file
uploaded_videos=/home/pi/Documents/uploaded_videos.txt

# Will expand non-matching globs to nothing:
shopt -s nullglob

# cd into the directory, and exit if fails
cd /home/pi/Documents || exit

# Use the builtin pwd instead of echo "$PWD"
pwd

for file in /media/pi/*/*.mp4; do
    if ! grep -qFx "$file" "$uploaded_videos"; then
        # Define an array to contain the arguments to pass
        args=(
            --file="$file"
            --title="$file"
            --description="show 2018"
            --keywords="2018,show, Winter,show 2018,"
            --category="28"
            --privacyStatus="private"
            )
        # call your script with the fields of the array as arguments
        python yt_up.py "${args[@]}"
        echo "$file uploaded to youtube via google developer api" | logger
        echo "$file" >> "$uploaded_videos"
    fi
done

You could improve the final step by explicitly checking whether yt_up.py succeeded:

if python yt_up.py "${args[@]}"; then
    echo "$file uploaded to youtube via google developer api" | logger
    echo "$file" >> "$uploaded_videos"
else
    echo "Something wrong happened!"
fi

Upvotes: 2

layekams
layekams

Reputation: 49

I think you have just to add you argument at in same line as python command. like this

python yt_up.py --file="${_file}" –-title="${_file}" --description="show 2018" --keywords="2018,show, Winter,show 2018," -–category="28" --privacyStatus="private"

It works

Upvotes: 0

Related Questions