В Unix, как Вы удаляете все в текущем каталоге и ниже его?

Кажется, что невозможно обойти эту проблему (по крайней мере, в Hadoop 2.7), поэтому на данный момент я добавил утверждение после каждой записи Spark S3, гарантируя, что количество частей файла соответствует количеству разделов в наборе данных. СДР:

  def overwriteParquetS3(
    ds: Dataset[_],
    bucket: String,
    folder: String
  ): Unit = {
    val numPartitions = ds.rdd.getNumPartitions
    val destination = GeneralUtils.joinPaths("s3a://", bucket, folder)

    ds
        .write
        .mode(SaveMode.Overwrite)
        .parquet(destination)

    val fs = FileSystem.get(
      URI.create(s"s3a://$bucket/"),
      ds.sparkSession.sparkContext.hadoopConfiguration
    )
    val writtenFiles = fs.listFiles(new Path(destination), false)
    val parts = new ArrayBuffer[LocatedFileStatus]()
    while (writtenFiles.hasNext) {
      val next = writtenFiles.next()
      val name = next.getPath.getName
      if (name.startsWith("part-") && name.endsWith(".parquet")) {
        parts += next
      }
    }

    val filePartStr = parts
        .sortBy(_.getPath.getName)
        .map((fileStatus) => s"${fileStatus.getModificationTime} ${fileStatus.getBlockSize} ${fileStatus.getPath.getName}")
        .mkString("\n\t")
    assert(
      parts.length == numPartitions,
      s"Expected to write dataframe with $numPartitions partitions in $destination but instead " +
          s"found ${parts.length} written parts!\n\t$filePartStr"
    )

    println(s"Confirmed that there numPartitions $numPartitions = ${parts.length} written parts")
  }

Похоже, это ловит все случаи, когда запись должна давать ошибку, но это не так.

108
задан Sam 17 August 2014 в 14:04
поделиться

9 ответов

Практика безопасных вычислений. Просто поднимитесь на один уровень в иерархии и не используйте подстановочное выражение:

cd ..; rm -rf -- <dir-to-remove>

Две черты - сообщают rm , что не является параметром командной строки, даже если он начинается с тире.

166
ответ дан 24 November 2019 в 03:26
поделиться

Использование

rm -rf *

Обновление: . обозначает текущий каталог, но мы не можем использовать это. Кажется, что команда имеет явные проверки для . и .. . Вместо этого используйте подстановочный знак. Но это может быть рискованно.

Более безопасная версия IMO должна использовать:

rm -ri * 

(это запрашивает подтверждение перед удалением каждого файла / каталога.)

21
ответ дан 24 November 2019 в 03:26
поделиться

убедитесь, что уверены , что вы находитесь в правильном каталоге

rm -rf *
4
ответ дан 24 November 2019 в 03:26
поделиться
rm  -rf * 

Не делайте этого! Это опасно! УБЕДИТЕСЬ, ЧТО ВЫ В ПРАВИЛЬНОЙ КАТАЛОГИ!

5
ответ дан 24 November 2019 в 03:26
поделиться

Удалит все файлы / каталоги ниже текущего.

find -mindepth 1 -delete

Если вы хотите сделать то же самое с другим каталогом, имя которого у вас есть, вы можете просто назвать это

find <name-of-directory> -mindepth 1 -delete

Если вы хотите чтобы удалить не только его подкаталоги и файлы, но и сам каталог, пропустите -mindepth 1 . Сделайте это без -delete , чтобы получить список вещей, которые будут удалены.

43
ответ дан 24 November 2019 в 03:26
поделиться

То, что я всегда делаю, это набираю

rm -rf *

и , затем нажимаю ESC - * , и bash расширит * до явного списка файлов и каталогов в текущей рабочей directory.

Преимущества:

  • Я могу просмотреть список файлов, которые нужно удалить, прежде чем нажать ENTER.
  • История команд не будет содержать «rm -rf *» с подстановочным знаком, который может быть случайно повторно используется в неправильном месте в неподходящее время. Вместо этого в истории команд будут содержаться реальные имена файлов.
  • Также стало удобно один или два раза ответить «подождите секунду ... какие файлы я только что удалил?». Имена файлов видны в буфере обратной прокрутки терминала или в истории команд. На самом деле, мне это так нравится, что я сделал его поведением по умолчанию для TAB с этой строкой в ​​.bashrc:

    bind TAB:insert-completions
    
40
ответ дан 24 November 2019 в 03:26
поделиться

It is correct that rm –rf . will remove everything in the current directly including any subdirectories and their content. The single dot (.) means the current directory. be carefull not to do rm -rf .. since the double dot (..) means the previous directory.

This being said, if you are like me and have multiple terminal windows open at the same time, you'd better be safe and use rm -ir . Lets look at the command arguments to understand why.

First, if you look at the rm command man page (man rm under most Unix) you notice that –r means "remove the contents of directories recursively". So, doing rm -r . alone would delete everything in the current directory and everything bellow it.

In rm –rf . the added -f means "ignore nonexistent files, never prompt". That command deletes all the files and directories in the current directory and never prompts you to confirm you really want to do that. -f is particularly dangerous if you run the command under a privilege user since you could delete the content of any directory without getting a chance to make sure that's really what you want.

On the otherhand, in rm -ri . the -i that replaces the -f means "prompt before any removal". This means you'll get a chance to say "oups! that's not what I want" before rm goes happily delete all your files.

In my early sysadmin days I did an rm -rf / on a system while logged with full privileges (root). The result was two days passed a restoring the system from backups. That's why I now employ rm -ri now.

6
ответ дан 24 November 2019 в 03:26
поделиться

Как насчет:

rm -rf "$(pwd -P)"/* 
5
ответ дан 24 November 2019 в 03:26
поделиться

Вероятно, это простейшее безопасное и общее решение:

find -mindepth 1 -maxdepth 1 -print0 | xargs -0 rm -rf
2
ответ дан 24 November 2019 в 03:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: