Welcome to the Linux Foundation Forum!

trouble with name increment

jaaf
jaaf Posts: 7
edited January 2012 in Command Line

Hi,

I am trying to write a script that records a window on my screen. No pb with that.

To go further I would like to choose an incremental fileName for output incrementing if the fileName already exist.

I have trouble doing it so before dealing with the incrementation itself, I want to check I can substitute the calculated name in the ffmpeg command.

filename="~/Bureau/essai"

index=1 #I will deal with the incrementation of index after this part works

mystring="${fileName}${index}.mkv" #omce I have a proper index I concatenate the name with index and name extension

echo ${mystring} # gives ~/Bureau/essai1.mkv seems to be what I expect

ffmpeg -f alsa ..... -y ${mystring}


I get this message

~/Bureau/essai1.mkv No such file or directory

despite -y to force overwriting

However if I put the file name directly in the command like this

ffmpeg -f alsa ..... -y ~/Bureau/essai1.mkv

it works perfectly. My question is : "What is wrong ?"

Comments

  • mfillpot
    mfillpot Posts: 2,177
    The script appears sane, so I do not see exactly what it wrong unless you have messed up something that is case sensitive, such as your use of the FileName variable when assigning to mystring.

    I have cleaned up the base script below:
    #!/bin/bash                                                                                                                                                                 
                                                                                                                                                                                
    filename="~/Bureau/essai"                                                                                                                                                   
    index=1 #I will deal with the incrementation of index after this part works                                                                                                 
    mystring="${filename}${index}.mkv" #omce I have a proper index I concatenate the name with index and name extension                                                         
    echo ${mystring} # gives ~/Bureau/essai1.mkv seems to be what I expect                                                                                                      
    echo "ffmpeg -f alsa .....  -y ${mystring}"
    

    use that script to get the expected output, then try to copy and run the last output line to see if that differs from manual input.

    Once you get this working I can help you to handle the name increments and testing to see if files exist.
  • jaaf
    jaaf Posts: 7
    hi, thank you for your help.
    I did what you suggested and it works fine.

    But what to do after that ? I tried to put the last echo line between back tits but the error message is still the same.
    ~/Bureau/video1.mkv: No such file or directory
  • jaaf
    jaaf Posts: 7
    here is the full script (my first one -adaptation - so be indulgent)

    #!/bin/sh
    #la ligne précédente indique que c'est un script bash. IL ne doit y avoir aucun caractère ou espace avant.
    #Une ligne qui commence par un dièse est un commentaire. Comme cette ligne.
    #Nous informons l'utilisateur
    echo "\n Vous démarrez un enregistrement vidéo. Veuillez cliquer sur la  fenêtre à enregistrer\n"
    #Nous demandons au système les informations sur la fenêtre cliquée
    INFO_FENETRE=$(xwininfo -frame)
    #la commande attend le clic
    #Nous affichons les informations
    echo "\n Information sur la fenêtre \n" $INFO_FENETRE+"\n\n"
    LARGEUR=$(echo $INFO_FENETRE | grep -oEe 'Width: [0-9]+' | grep -oEe '[0-9]+' )
    echo "Largeur trouvée : "$LARGEUR
    LARGEUR=$(($LARGEUR/2))
    LARGEUR=$(($LARGEUR*2))
    echo "Largeur corrigée : "$LARGEUR
    HAUTEUR=$(echo $INFO_FENETRE | grep -oEe 'Height: [0-9]+' | grep -oEe '[0-9]+')
    echo "Hauteur trouvée : "$HAUTEUR
    HAUTEUR=$(($HAUTEUR/2))
    HAUTEUR=$(($HAUTEUR*2))
    echo "Hauteur corrigée : "$HAUTEUR
    DECALAGE_FENETRE=$( echo $INFO_FENETRE | grep -oEe 'Corners:\s+\+[0-9]+\+[0-9]+' | grep -oEe '[0-9]+\+[0-9]+' | sed -e 's/\+/,/' )
    echo "Décalage fenêtre: "$DECALAGE_FENETRE"\n\n"
    #nous affichons la commande pour détection d'erreur s'il y a lieu.
    #echo "\n ffmpeg -f alsa -ac 1 -i hw:1,0 -acodec flac -f x11grab -s "$LARGEUR"x$HAUTEUR -i :0.0+$DECALAGE_FENETRE -r 10 -vcodec libx264 -vpre lossless_ultrafast ~/Bureau/essai.mkv "+"\n\n"
    #la commande proprement dite
    
    filename="~/Bureau/video"
    index=1 #will deal with index later
    mystring="${filename}${index}.mkv"
    echo "ffmpeg -f alsa -ac 1 -i hw:1,0 -acodec flac -f x11grab -s $LARGEUR"x"$HAUTEUR -i :0.0+$DECALAGE_FENETRE -r 15 -vcodec libx264 -vpre lossless_ultrafast  -y ${mystring}"
    

    the output is
    ffmpeg -f alsa -ac 1 -i hw:1,0 -acodec flac -f x11grab -s 1042x360 -i :0.0+ -r 15 -vcodec libx264 -vpre lossless_ultrafast  -y ~/Bureau/video1.mkv
    

    and the output command works!

  • jaaf
    jaaf Posts: 7
    I went a little further

    This works (removing double quotes) :

    filename=~/Bureau/video
    index=1
    mystring=${filename}${index}.mkv
    
    ffmpeg -f alsa -ac 1 -i hw:1,0 -acodec flac -f x11grab -s $LARGEUR"x"$HAUTEUR -i :0.0+$DECALAGE_FENETRE -r 15 -vcodec libx264 -vpre lossless_ultrafast  -y  ${mystring}
    

    but this doesn't (replacing ~ with /home/user)

    filename=/home/jaaf/Bureau/video #I am jaaf
    index=1
    mystring=${filename}${index}.mkv
    
    ffmpeg -f alsa -ac 1 -i hw:1,0 -acodec flac -f x11grab -s $LARGEUR"x"$HAUTEUR -i :0.0+$DECALAGE_FENETRE -r 15 -vcodec libx264 -vpre lossless_ultrafast  -y  ${mystring}
    

    How comes ?
  • mfillpot
    mfillpot Posts: 2,177
    I took the original script and replaces the ~ with the $HOME variable and it was able to output into the correct file with no new errors, it looks like ffmpeg was having problems dealing with the ~ character when navigating the filesystem.
  • jaaf
    jaaf Posts: 7
    Ok thank you again.
    For my problem instead of using an index, I'll use a date based extension to the name like this :
    ffmpeg -f alsa -ac 1 -i hw:1,0 -acodec flac -f x11grab -s $LARGEUR"x"$HAUTEUR -i :0.0+$DECALAGE_FENETRE -r 15 -vcodec libx264 -vpre lossless_ultrafast  -y video`date +%Y`.`date +%m`.`date +%H`.`date +%M`.`date +%S`.mkv &
    
  • mfillpot
    mfillpot Posts: 2,177
    The choice to use a date based assignment is better for organization and it should lead to no duplication, but it would not hurt to build error handling for duplicate names as a cautionary tool. Do you know how to use bash to check for existing files?
  • jaaf
    jaaf Posts: 7
    I read a bit about it but I cannot pretend I master it.
    I am very interrested in learing more as I am a beginner with bash scipting

    A few examples would be welcome.

  • mfillpot
    mfillpot Posts: 2,177
    edited January 2012
    Then here is a good example of filename error handling and implementing a formatted sequence number to force creation of a new valid name.
    #!/bin/bash
    
    filedir="${HOME}/testscripts/emptydir/"
    filename="testfile"
    fileext=".txt"
    
    # format the date as year-month-date so it can be easily sorted
    dt=$(date +"%y-%m-%d")
    
    # loop through from 1 to 999
    #  adding each three digit number to the filename
    #  until a number that does not exist if found,
    #  then make the file with the available name
    
    # use the seq command to increment a number, it is being formatted
    #  as a 3 digit number from 1 to 999
    for seqnum in $(seq -f "%03g" 1 999)
    do
      # set a filename including the directory, base name,
      #  date, sequence number and the extension
      fullfile="${filedir}${filename}-${dt}-${seqnum}${fileext}"
    
      # test the see if the file exist, first test to see
      #  if it does not exist
      #
      # the ! means NOT
      # the -f tests to see if the file exists
      # so "! -f" means check to see if the file does not exist
      #
      if [ ! -f ${fullfile} ]
      then
        # since the file does not exist, make it
        touch ${fullfile}
        echo "  ${fullfile} has been created"
    
        # exit the loop since the file has been created
        break
      fi
    done
    
  • jaaf
    jaaf Posts: 7
    Thank you for this. I think I understand. I just have a little problem understanding the letter g in %03g (I am not a computer scientist even if already wrote programms in Java and C++). . I think I have to read the c printf function quietly.

  • mfillpot
    mfillpot Posts: 2,177
    Honestly it does not match the proper printf floating point syntax, I have been using it for a while after I found it on the net. I am assuming that the synax is stating to have leading zeros while forcing whole numbers to be three characters long.
  • marc
    marc Posts: 647
    for seqnum in $(seq -f "%03g" 1 999)
    

    Whats wrong with:
    for seqnum in {001..999}
    
  • marc
    marc Posts: 647
    filename="~/Bureau/essai"
    

    This assings the character "~" which is not replaced by your home directory. Your command failed because you don't have a file called "~/Bureau/essai"

    Now:
    filename=~/Bureau/video
    

    You don't know what you are doing there, do you? hehehe That's a binary operator like "==" That has nothing to do with "~" being your home directory!!! The command, however, should work although not with the expected file name ;)

    About these:
    but this doesn't (replacing ~ with /home/user)
    
    
    filename=/home/jaaf/Bureau/video #I am jaaf
    
    index=1
    
    mystring=${filename}${index}.mkv
    
    
    
    ffmpeg -f alsa -ac 1 -i hw:1,0 -acodec flac -f x11grab -s $LARGEUR"x"$HAUTEUR -i :0.0+$DECALAGE_FENETRE -r 15 -vcodec libx264 -vpre lossless_ultrafast  -y  ${mystring}
    

    What's the output? Could it be possible that you didnt have the "Bureau" folder?

    General suggestions:

    1- ALWAYS ALWAYS ALWAYS use quotes
    2- use [[ instead of [
    3- ALWAYS use quotes
    4- don't use "break" it's bad programming style (generally) and you can do the same with a "while" and a variable to exit
    5- did I mention to ALWAYS use quotes?

    Regards
  • mfillpot
    mfillpot Posts: 2,177
    Marc,
    thanks for the input. I tried using "for seqnum in {001..999}" in a loop and it did not work, if you can correct the syntax I would love to note it for my uses.

    As for using break, I agree that it is generally bad to use it. However in this case where I was using a for loop to increment a number I was looking for something to exit the loop at the correct condition while using as few resources as possible. If you know a better was to do it while preserving the increments I would like to see it.
  • wow.. I think I slowly started to love scripting..
    Waiting for the prblem to be solved in this case.. :-)

    And Marc, ofcourse you mentioned, "ALWAYS", always ;-)
  • marc
    marc Posts: 647
    use the C style for

    for (( i=0,k=0;i<10,k<1;i++ ));do
    # This does what you need with the numbers
    printf "%02d" $i;
    # Whenever you reach the condition to exit the for loop
    k=1;
    done

    Regards

Categories

Upcoming Training