sobota 10. srpna 2024

wrapovací funkce pro rm (rmh) pro složky ~

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 -g important_dirs=(~/Obrázky ~/Dokumenty ~/Projekty)
declare -g min_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 "$@"; do
    if [[ $arg =~ ^\. ]]; then
      echo "Relativní cesta není povolena"
      return 1
    fi
  done

  for dir in "${important_dirs[@]}"; do
    expanded_dir=$(expand_path "$dir")
    expanded_arg=$(expand_path "$1")

    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

  rm "$@"
}
2. ROZŠÍŘENÁ VERZE
 
# @TODO: Opravit logiku a scházející proměnné:
#declare -g important_dirs=(~/Obrázky ~/Dokumenty ~/Projekty)
#declare -g min_dirs_required=(~/Obrázky 2 ~/Dokumenty 1 ~/Projekty 3) 
# Nové proměnné - @TODO: Implement
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"
) 
# @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 "$@"; do
    if [[ $arg =~ ^\. ]]; then
      echo "Relativní cesta není povolena"
      return 1
    fi
  done

  for 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 ]]; then
       echo "Povoleno je pouze mazání souborů v domovském adresáři uživatele."
       return 1
     fi 
     # 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 ]]; 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
 
    # 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
 rm "$@"
} 
  

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

GPT: Ramdisk a extrakce .deb

  Následující skript provádí popsané kroky, využívá RAMdisky různých velikostí podle potřeby a provádí extrakci. Tento skript je psán v Bas...

Štítky

.profile adm administrace Adobe AI akcelerace alfa transparence AND any aplikace apt ar archiv asociativní pole atomicity audio autentifikace awk balíčkovací systém bash beacon beacon_hint benchmark Bézierovy křivky bezpečnost biblehub BJT boolean buffer buffering Cache-Conrol Cloudflare code Collector Cut-off ColorManager colorpicker common compare config cookies CPU CPU pipe css CSS3 curl cut čas data loss data lost data transfer reliability datasheet datetime.strptime deb deb-systemd-helper debian debián development dioda diody dpkg dpkg -S dpkg-deb drivers EBO Emitter Cut-off Current eps ETag exclude exec Expires extrakce jediného extrakce názvu balíčku souboru extrakce souboru .deb fflock fflush ffmpeg FIFO file read file write file_get_contents file_get_contents/file_put_contents file_put_contents filter find first_install.sh flock Fly-back dioda font-face fóra fotorezistor fread functions funkce fwrite gate gate drive GDVfs gedit gedit-common geolokace Ghostscript GIO glib gnome gnome settings GNU Privacy Guard gnupg gpg gradient-background grafika grep grep -v groupadd grub grub update gs gsettings gtk gtk.css gtk+ hebrejština history hlavičky HS html html 5 https hudba charakterizace chroot chyba ICES IGBT img sizes img srcset impedance implementace imshow inference inkscape inrush current install jalový výkon javascript javescript jednocení seznamů js kapacita součástek koeficient zesílení komponenty xFce komunikace se serverem konfigurace Krita KSF Last-Modified lazy caching led LEFT JOIN librosa ligatury light-locker lightdm linux list log maják manuál maskování maskování služby masky matplotlib Max-Age measure memory měření MFCC MFCC koeficienty mint Mint 21.3 Mint xFce míry modules moralizace morphologie MOSFET mount moviepy mysql náběhový proud napěťová ochrana návod nel Network Error Logging NLP not Notifications NTFS nth-child oblékání ochrana okruhy přátel OpenVINO IR formát oprava oprava balíčku optočlen org.gnome.desktop.screensaver org.gnome.nm-applet ořezové masky OSHB otázky otázky_jazyky otázky_moralismu_řešení ovladače panely parsování path personifikace photorec php php 4 php 5 php 6 php 7 php 8 phpbb phpBB3 PipeWire pitch PN přechody pnp pole Policykit postscript práva profilování program prune průraz přeinstalování přepěťová ochrana přepolování příkazy připojení k síti připojení k wifi pseudokódd pstoedit PulseAudio PWM regulátory pydub python python3 pytorch ramdisk RBE RDSon read reaktance rectifier regulace vstupního napětí reinstall relyability remount replace restore reverzní geolokace RIGHT JOIN rm role rozvržení disků pro OS linux a data databází řešení samba sdílení sdílení souborů Sec-Fetch-Dest Sec-Fetch-Mode Sec-Fetch-Site Sec-Fetch-User Secure Shell sed Set Cookie show-manual-login show-remote-login shunt schemas schémata schottka skript skupiny sloupce služby song sort soubory soundfile spínané zdroje spínání splines split správa diskových zařízení SQL ssh stabilizace napětí stahování stream string strojové učení stropové učení supplicant svg syntax systemctl systemd-logind T5 tabulky Tangentové úsečky tar témata tepelná ztráta test text-shadow themes thermal runaway time timestamp tkinter tr transistor transition tranzistor tranzistory tuple tvorba otázek TVS ubuntu účiník udiskd udisks unconfined underrun unity-greeter update usermod uživatelé va charakteristika vala vektorová grafika Vgs video Vth vynechání adresářů vývoj while wpa wpa_supplicant wrapovací funkce x xandr xapp-watt xargs -I xed xed-common xfdesktop xml XOR Xorg Xorg Thumbnails xrandr závislosti zdánlivý výkon zdroj zenerka zenerovo napětí zip zip archiv zkratky zpomalení zpracování textu Žalmy