UNIX, как заставить мой скрипт удалять несколько файлов и подстановочные знаки? - PullRequest
1 голос
/ 24 мая 2019

Мне было поручено создать сценарий удаления, имитирующий команду rm. Как вы знаете, команда rm удаляет все файлы, если вы наберете что-то вроде rm file1 file2. Используя этот пример, мой скрипт будет удалять только файл2. Может кто-нибудь помочь мне, как сделать так, чтобы мой скрипт удаления удалил все перечисленные файлы? Мой скрипт ниже. Я прошу прощения, если это немного грязно, я новичок в кодировании.

    #!/bin/bash

       function directory(){
       #Checks if deleted directory & .restore.info file exists
       #If they don't exist, it creates them
       if [ ! -d ~/deleted ]
           then
               mkdir ~/deleted
       fi

      if [ ! -f ~/.restore.info ]
          then
              touch ~/.restore.info
      fi
      }

      function movefile(){
      #not currently using
      mv "$1" ~/deleted/$1
      echo "file moved to recycle bin"
      }

      function error_conditions(){
      #not currently using
      #Prints error messages and checks if file is in project directory
      if [ ! -f ~/project ]
          then
              echo "cannot remove $filename: no such file or directory"
      elif [ -d ~/project ]
              then
                  echo "cannot remove $filename: is a directory"
      else
          echo "missing operand"
      fi
      }

      function delete_file(){
      #Gets inode for filename
      #Takes user input and puts file wherever based on user input
      inode=$(stat -c%i "$filename")
      pwd=$(readlink -e $filename)
      if "$interactive"
          then
              if [ "$verbose" = true ]; then
                  read -p "Are you sure you want to delete $filename? " user_input
                      if [ $user_input == "y" ] || [ $user_input == "Y" ] || [ $user_input == "yes" ] || [ $user_input == "Yes" ];
                          then
                      mv $filename ~/deleted/${filename}_$inode
                      #moves deleted file to deleted directory (with inode at end)
                      echo ${filename}_$inode:$pwd>>~/.restore.info
                      #stores info of removed file in .restore.info (with path)
                      echo "removed '$filename'"
                          else
                          echo "Nothing has been deleted"
                      fi
              else
                  read -p "Are you sure you want to delete $filename? " user_input
                      if [ $user_input == "y" ] || [ $user_input == "Y" ] || [ $user_input == "yes" ] || [ $user_input == "Yes"];
                      then
                      mv "$filename" ~/deleted/${filename}_$inode
                      echo ${filename}_$inode:$pwd>>~/.restore.info
                      else
                      echo "Aborted"
              fi
          fi
      elif "$verbose"
          then
              mv "$filename" ~/deleted/${filename}_$inode
              echo ${filename}_$inode:$inode:pwd>>~/.restore.info
              echo "removed '$filename'"
      else
          mv "$filename" ~/deleted/${filename}_$inode
          echo ${filename}_$inode:$pwd>>~/.restore.info
          echo "Executed"
  fi
  }
  #Setting all flags to false
  interactive=false
  verbose=false
  recursive=false
  while getopts :ivr optionvar
  do
      case "$optionvar" in
          i) interactive=true;;
          v) verbose=true;;
          r) recursive=true;;
      esac
  done
  shift $((OPTIND-1)) #process arguments.
  #doing error commands with help of recursive
  for i in $*
      do
  filename=$i
  basefile=$(basename $i)
  if [ "$filename" == " " ];
      then
          echo "No filename provcided"
      elif [ -d $filename ];
          then
              if [ ! $recursive = true ];
                 then
                     echo "Directory name provided, please provide a file"
             fi
     elif [ ! -f $filename ];
         then
             echo "File does not exist"
     #   elif [ "$basefile" == "safe_rm" ]
     #   then
     #       echo "Attempting to delete safe_rm"
 fi
 done
 #################################M A I N###############################
 directory
 delete_file $*
 #error_conditions $* #- this gives me duplicate output lines
 #movefile "$@" - this gives me an unnecessary "mv: cannot stat" output line

1 Ответ

0 голосов
/ 24 мая 2019

Я не собираюсь делать подробный обзор кода всего вашего скрипта, но вот несколько замечаний.

  • Вы перебираете аргументы в основной части вашего скрипта, нотогда вы вызываете функцию удаления с несколькими аргументами.Эта функция не имеет зацикливания.Переместите цикл с main() на delete_files() (и обратите внимание, что я для краткости расшифровал его имя).
  • Говоря о main(), вы также можете инкапсулировать этот код (обработка опций, диспетчеризация функции,и т. д.) в функции с таким именем в нижней части скрипта есть строка, которая вызывает его: main "$@"
  • Не используйте $*, если вам не нужно то, что он делает, и не понимаете его использование- вместо этого используйте "$@" почти всегда и всегда заключайте его в кавычки (с очень редкими исключениями)
  • Используйте отступ последовательно
  • Если ваш сценарий не должен быть переносимым наоболочки, отличные от Bash, затем используйте специфичные для Bash функции, такие как [[ ]] вместо [ ]
  • . Вы используете оба способа именования функции одновременно (function f()).Используйте одно или другое - парены лучше, чем function, поэтому f () { ...; }
  • Используйте больше цитат, некоторые примеры:
    pwd=$(readlink -e "$filename")
    mv "$filename" ~/deleted/"${filename}_$inode"
    echo "${filename}_$inode:$pwd" >> ~/.restore.info
  • Но я не рекомендую использовать тильду (~) в скриптах - вместо этого используйте $HOME.И если вам нужно найти домашний каталог пользователя, используйте getent вместо других методов.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...