0

i just writing a script for make a Symbolic Links, but i think i have too much line can be much less with array, but i don't find an example with an explaniation for put multiples path in array.

The code i write is this :

#!/usr/bin/env bash

echo '
Autor ----------------> Inukaze ( Venezuela )
Sitio ----------------> https://goo.gl/ij6WqW
Correo-E -------------> bloginukaze@gmail.com
Licencia -------------> GPL 2

******* Inicio : Acerca de este Guión ********
  
  Es un guion simple para enlazar las partidas
  y configuraciones del emulador PPSSPP
  
******** Fin : Acerca de este Guión **********'

#Phantasy Star Portable 2
cd "./PhantasyStarPortable2"

#Version EUR (PAL)
Enlace="../../memstick/PSP/SAVEDATA/ULES01439"
if [ -L ${Enlace} ] ; then
   if [ -e ${Enlace} ] ; then
      echo "Enlace Funcional"
   else
      echo "Enlace Roto"
   fi
elif [ -e ${Enlace} ] ; then
   echo "No es un Enlace"
else
   echo "No existe"
ln -s "$PWD"    "$Enlace"   
fi

Enlace="../../memstick/PSP/SYSTEM/ULES01439_ppsspp.ini"
if [ -L ${Enlace} ] ; then
   if [ -e ${Enlace} ] ; then
      echo "Enlace Funcional"
   else
      echo "Enlace Roto"
   fi
elif [ -e ${Enlace} ] ; then
   echo "No es un Enlace"
else
   echo "No existe"
ln -s "$PWD/PSP2Conf.ini"   "$Enlace"
fi

#Version USA (NTSC)
Enlace="../../memstick/PSP/SAVEDATA/ULUS10529"
if [ -L ${Enlace} ] ; then
   if [ -e ${Enlace} ] ; then
      echo "Enlace Funcional"
   else
      echo "Enlace Roto"
   fi
elif [ -e ${Enlace} ] ; then
   echo "No es un Enlace"
else
   echo "No existe"
ln -s "$PWD" "$Enlace"  
fi

Enlace="../../memstick/PSP/SYSTEM/ULUS10529_ppsspp.ini"
if [ -L ${Enlace} ] ; then
   if [ -e ${Enlace} ] ; then
      echo "Enlace Funcional"
   else
      echo "Enlace Roto"
   fi
elif [ -e ${Enlace} ] ; then
   echo "No es un Enlace"
else
   echo "No existe"
ln -s "$PWD/PSP2Conf.ini"   "$Enlace"
fi
cd ..

#Monster Hunter Freedom Unite (1)
cd "./MonsterHunterFreedomUnite1"

#Version USA (NTSC)
Enlace= "../../memstick/PSP/SAVEDATA/ULUS10391"
if [ -L ${Enlace} ] ; then
   if [ -e ${Enlace} ] ; then
      echo "Enlace Funcional"
   else
      echo "Enlace Roto"
   fi
elif [ -e ${Enlace} ] ; then
   echo "No es un Enlace"
else
   echo "No existe"
ln -s "$PWD" "$Enlace"  
fi

Enlace="../../memstick/PSP/SYSTEM/ULUS10391_ppsspp.ini"
if [ -L ${Enlace} ] ; then
   if [ -e ${Enlace} ] ; then
      echo "Enlace Funcional"
   else
      echo "Enlace Roto"
   fi
elif [ -e ${Enlace} ] ; then
   echo "No es un Enlace"
else
   echo "No existe"
ln -s "$PWD" "$Enlace"
fi

#Version EUR (PAL)
Enlace="../../memstick/PSP/SAVEDATA/ULES01213"
if [ -L ${Enlace} ] ; then
   if [ -e ${Enlace} ] ; then
      echo "Enlace Funcional"
   else
      echo "Enlace Roto"
   fi
elif [ -e ${Enlace} ] ; then
   echo "No es un Enlace"
else
   echo "No existe"
ln -s "$PWD" "$Enlace"
fi

Enlace="../../memstick/PSP/SYSTEM/ULES01213_ppsspp.ini"
if [ -L ${Enlace} ] ; then
   if [ -e ${Enlace} ] ; then
      echo "Enlace Funcional"
   else
      echo "Enlace Roto"
   fi
elif [ -e ${Enlace} ] ; then
   echo "No es un Enlace"
else
   echo "No existe"
ln -s "$PWD" "$Enlace"
fi
cd ..

Well i just want to use array to reduce the lines, i thing i had wrote a lot of unnecesary lines. i just want to make a Symbolic Link to a Folder and in the another a Symbolic Link directly to a file.

1
  • Why don't you just create the link and let it fail if the file exists? Is there any additional benefit of knowing if it's a symbolic link, a broken symbolic link or a normal file?
    – pLumo
    Sep 15, 2021 at 6:13

3 Answers 3

2

That seems to be multiple copies of the same code with different filename arguments. As you guessed, this can and should be replaced with an array and a for loop. Something like this:

files=("../../memstick/PSP/SAVEDATA/ULES01439"
       "../../memstick/PSP/SYSTEM/ULES01439_ppsspp.ini"
       "../../memstick/PSP/SAVEDATA/ULUS10529"
       "../../memstick/PSP/SYSTEM/ULUS10529_ppsspp.ini"
       "../../memstick/PSP/SAVEDATA/ULUS10391"
       "../../memstick/PSP/SYSTEM/ULUS10391_ppsspp.ini"
       "../../memstick/PSP/SAVEDATA/ULES01213"
       "../../memstick/PSP/SYSTEM/ULES01213_ppsspp.ini")

for Enlace in "${files[@]}" ; do
  if [ -L "$Enlace" ] ; then
    if [ -e "$Enlace" ] ; then
      echo "Enlace Funcional"
    else
      echo "Enlace Roto"
    fi
  elif [ -e "$Enlace" ] ; then
    echo "No es un Enlace"
  else
    echo "No existe"
    ln -s "$PWD" "$Enlace"   
  fi
done

Notes:

  1. your example filenames being defined in the files array don't actually need to be double-quoted, but doing so is a good habit to get in to because spaces and other annoying characters are valid characters in a filename.

  2. curly braces are NOT a substitute for quoting variables. They're only useful for disambiguating variable names - e.g. "$var_x" is referring to a variable called var_x, while "${var}_x" is referring to a variable called varfollowed by the literal string_x`. You still need to quote your variables, whether you need to use curly braces or not.

    However, the curly braces are required when using an array variable (e.g. as shown in the for Enlace in "${files[@]}" line). And when using shell parameter expansion.

  3. @muru pointed out that sometimes the code symlinks just "$PWD" and sometimes it symlinks "$PWD/PSP2Conf.ini"

    It's difficult to tell what you're actually doing, but I'm going to guess that the deciding factor there is whether "$Enlace" ends in .ini or not. If that's the case, then replace the ln -s "$PWD" "$Enlace" line with the following lines:

    if [[ $Enlace =~ \.ini$ ]] ; then 
      ln -s "$PWD/PSP2Conf.ini" "$Enlace"
    else
      ln -s "$PWD" "$Enlace"   
    fi
  1. You also seem to be changing directory somewhere in the middle of that script. That might mean you need to re-define the files array with appropriate values whenever you change directories, or maybe a more complex data structure like a hash of arrays (in which case, I'd use perl rather than bash), with the hash keys being the directory and the array elements being the symlink names to be created.

  2. It would be easier to accurately answer this question if you described what it was actually doing and why.

4
  • OP edited their original post so that now in some cases the ln command uses ln -s "$PWD/PSP2Conf.ini" .... An associative array might be useful here.
    – muru
    Sep 15, 2021 at 3:01
  • dunno if an associative array would be of much use here. maybe a multi-dimensional array, or a hash of arrays...in which case, i'd use awk or, more likely, perl instead of bash.
    – cas
    Sep 15, 2021 at 3:06
  • I'd make it a function, and then just call the function with the file names. Would make it much more readable.
    – pLumo
    Sep 15, 2021 at 5:59
  • Thanks for the answer. 5 : Is ease i use LiveUSB with GNU/Linux and i had my own version of PPSSPP but i eve share the save file (battery) between various pc. and because of that i prefer had my own directory/file structure because by game id i really dont remember which game are each. and this script is just for make symlinks to my own structure of Directories/Files
    – Inukaze
    Sep 19, 2021 at 19:47
0

This is more about programming in general, but I'd say repetition requires functions:

make_link() {
    Enlace=$2
    file=$1
    if [ -L "${Enlace}" ] ; then
       if [ -e "${Enlace}" ] ; then
          echo "Enlace Funcional"
       else
          echo "Enlace Roto"
       fi
    elif [ -e "${Enlace}" ] ; then
       echo "No es un Enlace"
    else
       echo "No existe"
       ln -s "$PWD"    "$Enlace"   
    fi
}
make_link "$PWD"              "../../memstick/PSP/SAVEDATA/ULES01439"
make_link "$PWD/PSP2Conf.ini" "../../memstick/PSP/SYSTEM/ULES01439_ppsspp.ini"
...

With that set up, you could use an array or something else to hold the data, instead of the hard coded list as above. Though with the runtime evaluation of $PWD needed here, that's not as straightforward as it could be.

0

I don't see much benefit of the whole script.

If you don't add -f (force) or -b (backup), ln -s will fail with "File exists" error, so you could simply run and let it fail.

enlace="../../memstick/PSP/SAVEDATA/ULES01439"
ln -s "$PWD" "$enlace"

If you need additional information about the file type if it exists, you can add file "$enlace", e.g.:

ln -s "$PWD" "$enlace" || file "$enlace"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.