0

I have a 4 functions that are 100 rows of simple code in my .bashrc

These functions are identical except for the function name and the first 3 lines of code which are variables.

How can I pull the 97 lines of code that are common out and into a seperate instantiated block that I then call from each of the 4 functions?

I tried making a common function block of these common 97 lines and calling that from a very small funcion but I could not get that to work.

Here is the function with the 3 unique lines at the top and the common code below that

function download_podcaster() 
   
######################################################################
##########                                                  ########## 
#   UNIQUE CODE FOLLOWS  #

#set-up the directory variables

dir_zz="/home/user/podcast_author"  
pone_dir="podcast_author"  
downloads_z="~/Downloads"  

##########   UNIQUE CODE ABOVE                              ##########
##########                                                  ########## 
######################################################################


#  vvvvv COMMON CODE BELOW   vvvvvv


   echo; echo "   .... this output is from youtube-dl ..."; echo

   #download the file
   youtube-dl -f 140 --restrict-filenames -o $dir_zz'/%(title)s.%(ext)s' $1


   #make dir if does not aleready exist
   mkdir -p $dir_zz

   #change to the downloads directory
   cd $dir_zz
   echo
   echo "current dir is:                                   "$(pwd)
   echo
  
   #open the downloads location to show the files with pcmanfm 
   #pcmanfm ~/Downloads &
   pcmanfm $dir_zz &> /dev/null
   
   file_name_z=$(youtube-dl --get-filename --restrict-filenames "$1")
   echo; echo "file name from provided by youtube-dl:            "$file_name_z; echo

   #grab the filename from youtube, and parse it into something useful
   #remove 11 digits before end of file name                
   file_name_z=$(echo $file_name_z | sed 's|...........\.mp4$|.mp4|g' | sed 's|...........\.m4a$|.m4a|g' \
       | sed 's|...........\.webm$|.webm|g' \
       | sed 's|,||g' | sed 's|!||g' | sed 's| |_|g'  |  \
       sed 's|-\.||g' | sed 's|webm||g' | sed 's|mp4||g' | sed 's|\?||g').m4a
           #  remove ,      remove !       replace " " with "_"
           #  remove "-."    remove "webm"
   echo; echo "file name after , ! \" \" ? removed:                "$file_name_z; echo

   var1=$(ls -t | grep -E "^[0-9]{3}" | sort | tail -n  1 | cut --bytes=1-3)
   echo; echo "\$var1 3 digit highest number from file set is:    "$var1; echo
   
   sleep .25
   #create the variable to assign the next file number to front of file name
   next_file_number=$(printf "%03d\n" $((10#$var1+5)))
   echo; echo "File number plus 5 is:                            "$next_file_number; echo

   sleep .25
   #new file name with three digit number in front of filename
   file_name_y=${next_file_number}_${file_name_z}
   echo; echo "concatenated filename is \$file_name_y:            ""$file_name_y"; echo


   #move the old file to the new file name
   mv "$file_name_z" "$file_name_y" 
   echo; echo "                                                  ""$file_name_y"; echo


   #plug phone in. Phone mount point in file system can be seen here
   #echo; cd /var/run/user/$UID/gvfs; ls; echo
   #reference
   #https://askubuntu.com/questions/342319/where-are-mtp-mounted-devices-located-in-the-filesystem
   #
   #How to get to the phone directory on the phone if the directory is dynamically allocated on the 
   #reference  
   #https://askubuntu.com/a/454697/624987
   #phone or changes, use this
   #cd /var/run/user/$UID/gvfs; cd * ; cd *; cd Music; mkdir -p $phone_dir; cd $phone_dir; ls
   #       
   #"cd *" changes to the first directory shown
   
   #grab the directory on the phone in which to place the file
   cd /var/run/user/$UID/gvfs; cd * ; cd *; cd Music; mkdir -p $phone_dir; cd $phone_dir
   phone_dir_long_path=$(pwd)


   echo "  ... now copying the file to the phone -->"; echo
   #copy file to phone
   cp $dir_zz/"$file_name_y" "$phone_dir_long_path"
   echo
   
   #open terminal at directory of files
   gnome-terminal --title="test" --command="bash -c '$phone_dir_long_path; ls; $SHELL'"

   echo
   #open the file name with the default app, usually vlc
   xdg-open $dir_zz/$file_name_y &

   echo
}

1 Answer 1

4

Use positional parameters:

download() {
    fdir_zz="$1"
    pone_dir="$1"
    downloads_z="$3"

    ...
}

download "/home/user/podcast_author" "podcast_author" ~/Downloads

Of course you can also set up functions so you don't need to type in this stuff:

download_podcaster(){
    download "/home/user/podcast_author" "podcast_author" ~/Downloads
}
download_something_else(){
    download ...
}

Alternative:

Use only one positional parameter and hard-code the rest with a case ... esac statement:

download(){
    case $1 in
        podcaster) 
            fdir_zz="/home/user/podcast_author"
            pone_dir="podcast_author"
            downloads_z="$HOME/Downloads"
            ;;
        something_else)
            fdir_zz="..."
            pone_dir="..."
            downloads_z="..."
            ;;
    esac

    ...
}

download podcaster
download something_else
3
  • thank you. Each of the 4 function instances hold all the information needed without me having to remember variables to passed as arguments to each one, each time, which I will definatley not be able to remember at time of use. I need to be able to do this as described. Surely there is a way ..
    – Kes
    Commented Sep 28, 2021 at 17:00
  • 1
    Sure, just use another functions, check my update.
    – pLumo
    Commented Sep 29, 2021 at 5:36
  • The alternative works, thanks
    – Kes
    Commented Sep 30, 2021 at 9:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .