Dotaz na LLamu 
Když se do deklarované bash funkce pro účely ~/.profile uvede pole, bude se toto pole načítat při každém volání funkce z terminálu, nebo lze pole uvnitř funkce nadeklarovat tak, aby zůstalo po celou dobu běhu terminálu a nevynulovalo se? Příklad. Nadefinujme funkci rmh, která bude předávat argumenty příkazu rm , ale bude wrapovací funkcí, která kontroluje bezpečnost argumentů. Například pokud argumenty obsahují relativní cestu, nebude povoleno spuštění rm. Dále bych deklaroval pole s adresáři, u kterých by bylo určena jejich důležitost podle minimálního počtu vyžadovaných adresářů v argumentu cesty. Např. pokud spustím rmh ~/Obrázky/*.jpg, bude se vyžadovat ještě min. jeden adresář v cestě, takže rm se nespustí. Aby se rm spustilo musela by cesta vypadat např. takto ~/Obrázky/designer/*.jpg , toto nastavení by bylo individuální podle toho v jakém adresáři se budu vyskytovat a specifikace by byla v tom poli.
V bashi je možné definovat pole uvnitř funkce tak, aby zůstalo po celou dobu běhu terminálu a nevynulovalo se. Jedním ze způsobů, jak toho dosáhnout, je použít deklaraci declare s atributem -g (globální) pro pole.
Příklad:
bash
rmh() {
  local -g important_dirs=(~/Obrázky ~/Dokumenty ~/Projekty)
  local -g min_dirs_required=(~/Obrázky 2 ~/Dokumenty 1 ~/Projekty 3)
  # Kontrola bezpečnost argumentů
  for arg in "$@"; do
    if [[ $arg =~ ^\. ]]; then
      echo "Relativní cesta není povolena"
      return 1
    fi
  done
  # Kontrola minimálního počtu adresářů v cestě
  for dir in "${important_dirs[@]}"; do
    if [[ $1 =~ $dir ]]; then
      local min_dirs=${min_dirs_required[$dir]}
      local dirs_in_path=$(echo "$1" | tr '/' '\n' | wc -l)
      if (( dirs_in_path < min_dirs )); then
        echo "Minimální počet adresářů v cestě nebyl splněn"
        return 1
      fi
    fi
  done
  # Spuštění příkazu rm
  rm "$@"
}ROZŠÍŘENÁ VERZE NAHRAZUJE ~ ZA DOMOVSKÝ ADRESÁŘ:
declare -gimportant_dirs=(~/Obrázky ~/Dokumenty ~/Projekty)declare -gmin_dirs_required=(~/Obrázky 2 ~/Dokumenty 1 ~/Projekty 3) expand_path() { if [[ $1 == ~* ]]; then echo "${1/#\~/$HOME}" else echo "$1" fi }rmh() {for arg in "$@"; doif [[ $arg =~ ^\. ]]; then echo "Relativní cesta není povolena" return 1 fidonefor dir in "${important_dirs[@]}"; doexpanded_dir=$(expand_path "$dir") expanded_arg=$(expand_path "$1")if [[ $1 =~ $dir ]]; thenlocal min_dirs=${min_dirs_required[$dir]}localdirs_in_path=$(echo "$1" | tr '/' '\n' | wc -l)if (( dirs_in_path < min_dirs )); then echo "Minimální počet adresářů v cestě nebyl splněn" return 1 fifi donerm "$@"}
 # @TODO: Opravit logiku a scházející proměnné:
#declare -gimportant_dirs=(~/Obrázky ~/Dokumenty ~/Projekty)#declare -gmin_dirs_required=(~/Obrázky 2 ~/Dokumenty 1 ~/Projekty 3)
# Nové proměnné - @TODO: Implementdeclare -g image_dirs=(~/Obrázky ~/Pictures ~/Fotky ~/Photo ~/Photos)
declare -g music_dirs=(~/Music ~/Hudba)
declare -g video_dirs=(~/Video ~/Videa ~/Videos)
declare -g document_dirs=(~/Documents ~/Dokumenty)
declare -g download_dirs=(~/Stažené ~/Downloads ~/Downloaded)
declare -g script_dirs=(~/Skripty ~/Scripts)
declare -g www_dirs=(~/www ~/www_projects)
declare -g pascal_dirs=(~/FreePascal)
# Povolené přípony souborů
declare -g image_extensions=("*.jpg" "*.jpeg" "*.png" "*.gif" "*.bmp" "*.svg" "*.ico")
declare -g music_extensions=("*.wav" "*.mp3" "*.m3u")
declare -g video_extensions=("*.avi" "*.mp4" "*.mov" "*.m4p")
declare -g document_extensions=("*.txt" "*.doc" "*.docx" "*.xls" "*.xlsx" "*.ppt" "*.pptx" "*.odt" "*.ods" "*.odp")
declare -g download_extensions=("*.zip" "*.tar" "*.gz" "*.bz2")
declare -g script_extensions=("*.sh" "*.py" "*.pl")
declare -g www_extensions=("*.js" "*.php" "*.txt" "*.jpg" "*.jpeg" "*.png" "*.gif" "*.bmp")
declare -g pascal_extensions=("*.pas" "*.lpr" "*.ppu" "*.o" "*.compiled") declare -g rm_options=(
  "-f" "--force" "-i" "-I" "--interactive" "--one-file-system"
  "--no-preserve-root" "--preserve-root" "-r" "-R" "--recursive"
  "-d" "--dir" "-v" "--verbose" "--help" "-h" "--version"
) # @TODO: Implement: how old files will be deleted# -old - if older then yesterday# -today-old-versions - specify latest file name which will not be deleted - exmaple: record_0021.avi should delete older versions of this file, today.
declare -g special_options=(
  "-old" "-yesterday" "-today" "-24h" "-2days" "old-versions-now"
)  expand_path() { if [[ $1 == ~* ]]; then echo "${1/#\~/$HOME}" else echo "$1" fi }rmh() {for arg in "$@"; doif [[ $arg =~ ^\. ]]; then echo "Relativní cesta není povolena" return 1 fidonefor dir in "${important_dirs[@]}"; do
    # Pokud je argument volbou pro rm, přeskočí kontrolu
    if [[ " ${rm_options[@]} " =~ " ${arg} " ]]; then
      continue
    fi     expanded_dir=$(expand_path "$dir")
    expanded_arg=$(expand_path "$1")      # Kontrola, zda argument začíná domovskou složkou uživatele
     if [[ ! $expanded_arg =~ ^$HOME ]]; thenfi      # Kontrola na nebezpečný znak '*'      if [[ $expanded_arg == $expanded_dir* ]]; then
       # Kontrola na nebezpečný znak '*'
       if [[ $arg =~ \* ]]; then
         # Kontrola, zda je název dostatečně specifikovaný
         if [[ $arg =~ \.[a-zA-Z0-9]+$ ]] || [[ $arg =~ [^*/]{3,}\* ]]; then
           if [[ ${#arg} -lt 5 ]]; then
             # Pokud je název souboru kratší než 5 znaků před koncovkou nebo hvězdičkou
             local file_count=$(ls "$arg" 2>/dev/null | wc -l)
             if (( file_count > 0 )); then
               echo -e "\e[33mPočet souborů, které budou smazány: $file_count\e[0m"
               ls "$arg"
               echo -e "\e[31mPozor: Argument obsahuje nebezpečný znak '*'. Opravdu chcete smazat soubory? [y/N]\e[0m"
               read -r confirmation
               if [[ $confirmation != "y" ]]; then
                 echo "Mazání zrušeno."
                 return 1
               fi
             else
               echo "Žádné soubory nebyly nalezeny."
               return 1
             fi
           fi
         else
           echo -e "\e[31mPozor: Argument obsahuje nebezpečný znak '*' a není dostatečně specifikován. Opravdu chcete smazat soubory? [y/N]\e[0m"
           read -r confirmation
           if [[ $confirmation != "y" ]]; then
             echo "Mazání zrušeno."
             return 1
           fi
         fi
       fi
     fi   if [[ $1 =~ $dir ]]; thenlocal min_dirs=${min_dirs_required[$dir]}localdirs_in_path=$(echo "$1" | tr '/' '\n' | wc -l)if (( dirs_in_path < min_dirs )); then echo "Minimální počet adresářů v cestě nebyl splněn" return 1 fifi
    # Zjištění, do které kategorie složek argument patří
    for dir in "${image_dirs[@]}"; do
      if [[ $expanded_arg =~ $dir ]]; then
        check_extension "$arg" "${image_extensions[@]}" || {
          echo "Nepovolený typ souboru v obrázkové složce: $arg"
          invalid_file=1
        }
      fi
    donefor dir in "${music_dirs[@]}"; do
        if [[ $expanded_arg =~ $dir ]]; then
          if ! check_extension "$arg" "${music_extensions[@]}"; then
            echo "Nepovolený typ souboru v hudební složce: $arg"
            invalid_file=1
            break
          fi
        fi
      donefordo
        if [[ $expanded_arg =~ $dir ]]; then
          if ! check_extension "$arg" "${video_extensions[@]}"; then
            echo "Nepovolený typ souboru ve video složce: $arg"
            invalid_file=1
            break
          fi
        fi
      donefor dir in "${document_dirs[@]}"; do
        if [[ $expanded_arg =~ $dir ]]; then
          if ! check_extension "$arg" "${document_extensions[@]}"; then
            echo "Nepovolený typ souboru v dokumentové složce: $arg"
            invalid_file=1
            break
          fi
        fi
      donefor dir in "${download_dirs[@]}"; do
        if [[ $expanded_arg =~ $dir ]]; then
          if ! check_extension "$arg" "${download_extensions[@]}"; then
            echo "Nepovolený typ souboru ve složce Stažené: $arg"
            invalid_file=1
            break
          fi
        fi
      donefor dir in "${script_dirs[@]}"; do
        if [[ $expanded_arg =~ $dir ]]; then
          if ! check_extension "$arg" "${script_extensions[@]}"; then
            echo "Nepovolený typ souboru ve složce Skripty: $arg"
            invalid_file=1
            break
          fi
        fi
      donefor dir in "${www_dirs[@]}"; do
        if [[ $expanded_arg =~ $dir ]]; then
          if ! check_extension "$arg" "${www_extensions[@]}"; then
            echo "Nepovolený typ souboru ve složce WWW: $arg"
            invalid_file=1
            break
          fi
        fi
      donefor dir in "${pascal_dirs[@]}"; do
        if [[ $expanded_arg =~ $dir ]]; then
          if ! check_extension "$arg" "${pascal_extensions[@]}"]; then
            echo "Nepovolený typ souboru ve složce FreePascal: $arg"
            invalid_file=1
            break
          fi
        fi
      donefor ext in "${sensitive_extensions[@]}"; do
        if [[ $arg == *"$ext" ]]; then
          echo -e "\e[31mOpravdu chcete smazat soubory s příponou '$ext'? [y/N]\e[0m"
          read -r confirmation
          if [[ $confirmation != "y" ]]; then
            echo "Mazání zrušeno."
            return 1
          fi
        fi
      donedonerm "$@"}
  3. Rozšíření (pokus o implementaci)
Následný skript by měl zahrnovat rozšíření o implementaci kontroly stáří souboru (nezkontrolováno).
declare -g image_dirs=(~/Obrázky ~/Pictures ~/Fotky ~/Photo ~/Photos)
declare -g music_dirs=(~/Music ~/Hudba)
declare -g video_dirs=(~/Video ~/Videa ~/Videos)
declare -g document_dirs=(~/Documents ~/Dokumenty)
declare -g download_dirs=(~/Stažené ~/Downloads ~/Downloaded)
declare -g script_dirs=(~/Skripty ~/Scripts)
declare -g www_dirs=(~/www ~/www_projects)
declare -g pascal_dirs=(~/FreePascal)
# Povolené přípony souborů
declare -g image_extensions=("*.jpg" "*.jpeg" "*.png" "*.gif" "*.bmp" "*.svg" "*.ico")
declare -g music_extensions=("*.wav" "*.mp3" "*.m3u")
declare -g video_extensions=("*.avi" "*.mp4" "*.mov" "*.m4p")
declare -g document_extensions=("*.txt" "*.doc" "*.docx" "*.xls" "*.xlsx" "*.ppt" "*.pptx" "*.odt" "*.ods" "*.odp")
declare -g download_extensions=("*.zip" "*.tar" "*.gz" "*.bz2")
declare -g script_extensions=("*.sh" "*.py" "*.pl")
declare -g www_extensions=("*.js" "*.php" "*.txt" "*.jpg" "*.jpeg" "*.png" "*.gif" "*.bmp")
declare -g pascal_extensions=("*.pas" "*.lpr" "*.ppu" "*.o" "*.compiled")
declare -g rm_options=(
  "-f" "--force" "-i" "-I" "--interactive" "--one-file-system"
  "--no-preserve-root" "--preserve-root" "-r" "-R" "--recursive"
  "-d" "--dir" "-v" "--verbose" "--help" "-h" "--version"
)
# Speciální možnosti pro kontrolu stáří souborů
declare -g special_options=(
  "-old" "-yesterday" "-today" "-24h" "-2days" "old-versions-now"
)
expand_path() {
  if [[ $1 == ~* ]]; then
    echo "${1/#\~/$HOME}"
  else
    echo "$1"
  fi
}
check_extension() {
  local file=$1
  shift
  local valid_extensions=("$@")
  for ext in "${valid_extensions[@]}"; do
    if [[ $file == $ext ]]; then
      return 0
    fi
  done
  return 1
}
check_age_and_delete() {
  local age=$1
  local path=$2
  local pattern=$3
  find "$path" -type f -name "$pattern" -mtime "$age" -exec rm {} \;
}
rmh() {
  invalid_file=0  # Proměnná pro sledování stavu neplatných souborů
  for arg in "$@"; do
    if [[ $arg =~ ^\. ]]; then
      echo "Relativní cesta není povolena"
      return 1
    fi
    expanded_arg=$(expand_path "$arg")
    # Zpracování speciálních možností pro stáří souborů
    if [[ " ${special_options[@]} " =~ " ${arg} " ]]; then
      case $arg in
        "-old")
          check_age_and_delete "+1" "$expanded_arg" "*"  # starší než včera
          ;;
        "-yesterday")
          check_age_and_delete "1" "$expanded_arg" "*"  # přesně včera
          ;;
        "-today")
          check_age_and_delete "0" "$expanded_arg" "*"  # starší než dnes
          ;;
        "-24h")
          find "$expanded_arg" -type f -mmin +1440 -exec rm {} \;  # starší než 24 hodin
          ;;
        "-2days")
          check_age_and_delete "+2" "$expanded_arg" "*"  # starší než 2 dny
          ;;
        "old-versions-now")
          # # -today-old-versions - specify latest file name which will not be deleted - exmaple: record_0021.avi should delete older versions of this file, today.
          # @TODO: Tuto logiku bude třeba detailněji implementovat
          ;;
      esac
      continue
    fi
    # Zjištění, do které kategorie složek argument patří
    for dir in "${image_dirs[@]}"; do
      if [[ $expanded_arg =~ $dir ]]; then
        check_extension "$arg" "${image_extensions[@]}" || {
          echo "Nepovolený typ souboru v obrázkové složce: $arg"
          invalid_file=1
        }
      fi
    done
    # Pokračování pouze pokud nebyl nalezen neplatný soubor
    if [[ ! $invalid_file -eq 1 ]]; then
      for dir in "${music_dirs[@]}"; do
        if [[ $expanded_arg =~ $dir ]]; then
          if ! check_extension "$arg" "${music_extensions[@]}"; then
            echo "Nepovolený typ souboru v hudební složce: $arg"
            invalid_file=1
            break
          fi
        fi
      done
    fi
    if [[ ! $invalid_file -eq 1 ]]; then
      for dir in "${video_dirs[@]}"; do
        if [[ $expanded_arg =~ $dir ]]; then
          if ! check_extension "$arg" "${video_extensions[@]}"; then
            echo "Nepovolený typ souboru ve video složce: $arg"
            invalid_file=1
            break
          fi
        fi
      done
    fi
    if [[ ! $invalid_file -eq 1 ]]; then
      for dir in "${document_dirs[@]}"; do
        if [[ $expanded_arg =~ $dir ]]; then
          if ! check_extension "$arg" "${document_extensions[@]}"; then
            echo "Nepovolený typ souboru v dokumentové složce: $arg"
            invalid_file=1
            break
          fi
        fi
      done
    fi
    if [[ ! $invalid_file -eq 1 ]]; then
      for dir in "${download_dirs[@]}"; do
        if [[ $expanded_arg =~ $dir ]]; then
          if ! check_extension "$arg" "${download_extensions[@]}"; then
            echo "Nepovolený typ souboru ve složce Stažené: $arg"
            invalid_file=1
            break
          fi
        fi
      done
    fi
    if [[ ! $invalid_file -eq 1 ]]; then
      for dir in "${script_dirs[@]}"; do
        if [[ $expanded_arg =~ $dir ]]; then
          if ! check_extension "$arg" "${script_extensions[@]}"; then
            echo "Nepovolený typ souboru ve složce Skripty: $arg"
            invalid_file=1
            break
          fi
        fi
      done
    fi
    if [[ ! $invalid_file -eq 1 ]]; then
      for dir in "${www_dirs[@]}"; do
        if [[ $expanded_arg =~ $dir ]]; then
          if ! check_extension "$arg" "${www_extensions[@]}"; then
            echo "Nepovolený typ souboru ve složce WWW: $arg"
            invalid_file=1
            break
          fi
        fi
      done
    fi
    if [[ ! $invalid_file -eq 1 ]]; then
      for dir in "${pascal_dirs[@]}"; do
        if [[ $expanded_arg =~ $dir ]]; then
          if ! check_extension "$arg" "${pascal_extensions[@]}"]; then
            echo "Nepovolený typ souboru ve složce FreePascal: $arg"
            invalid_file=1
            break
          fi
        fi
      done
    fi
    # Dodatečná výzva pro citlivé přípony
    if [[ ! $invalid_file -eq 1 ]]; then
      for ext in "${sensitive_extensions[@]}"; do
        if [[ $arg == *"$ext" ]]; then
          echo -e "\e[31mOpravdu chcete smazat soubory s příponou '$ext'? [y/N]\e[0m"
          read -r confirmation
          if [[ $confirmation != "y" ]]; then
            echo "Mazání zrušeno."
            return 1
          fi
        fi
      done
    fi
  done
  # Pokud byla nalezena jakákoli neplatná přípona, skript vrátí chybu
  if [[ $invalid_file -eq 1 ]]; then
    return 1
  fi
  # Spuštění příkazu rm s argumenty
  rm "$@"
} 
 
 
 
Žádné komentáře:
Okomentovat