Удалить каталог, ссылаясь на символическую ссылку

Чтобы задать вопрос, представьте себе такой сценарий:

mkdir ~/temp
cd ~/
ln -s temp temporary

rm -rf temporary, rm -f temporary и rm temporary каждый удалит символическую ссылку, но покинет каталог ~/temp/.

У меня есть сценарий, в котором имя символической ссылки легко выводится, а имя связанной директории - нет.

Есть ли способ удалить каталог, ссылаясь на символическую ссылку, если не считать синтаксического анализа имени каталога из ls -od ~/temporary?

2
задан 5 November 2013 в 23:03

2 ответа

Вы можете использовать следующую команду:

rm -rf $(ls -l ~/temporary | awk '{print $NF}')

Если вы не хотите анализировать ls, то вы можете использовать:

rm -rf $(file ~/temporary | awk '{print $NF}' | tr -d "\`\',")

или просто:

rm -rf $(readlink ~/temporary)

Чтобы позаботиться о пробелах как в имени каталога, так и в имени ссылки, вы можете изменить последнюю команду следующим образом

rm -rf "$(readlink ~/"temporary with spaces")"
0
ответ дан 5 November 2013 в 23:03
  • 1
    Все еще зафиксированный в 16.04 LTS. Этот ответ действительно имеет обходное решение, которое работало на меня. – Day 2 May 2017 в 00:51
поскольку я только что показал вам, что переменные, установленные внутри подоболочки, не могут быть видны родительской оболочкой. Вот где мы будем использовать printf с его модификатором %q:

$ ( cd test; printf '%q' "$PWD" )
 

Теперь, можем ли мы поместить stdout подоболочки в переменную? Конечно, просто добавьте подоболочку с помощью $:

$ labas=$(cd test; printf '%q' "$PWD")
$ echo "$labas"
 

( l & agrave; -bas означает там по-французски).

11139 Но что мы будем делать с этой глупой нитью? Полегче, будем использовать страшное, зло eval. Действительно, никогда, никогда, никогда не используйте eval. Это плохо. Бог убивает котенка каждый раз, когда вы используете eval. Действительно, поверь мне. Если, конечно, вы точно не знаете, что делаете. Если вы не уверены, что ваши данные были очищены. (Вы знаете Бобби Таблицы?). Но здесь, это так. Модификатор printf %q просто делает это для нас! Тогда:

rm_where_this_points_to() {
    local labas=$( cd -P -- "$1" && printf '%q' "$PWD" )
    [[ -z "$labas" ]] && { echo >&2 "Couldn't go where \`$1' points to."; return 1; }
    if [[ "$labas" = "$(printf '%q' "$PWD")" ]]; then
        echo >&2 "Oh dear, \`$1' points here exactly."
        return 1
    fi
    # eval and unquoted $labas, I know what I'm doing:
    # $labas has been sanitized and comes directly from `printf '%q'`
    eval "rm -rfv -- $labas"
}

Смотри, здесь есть кавычки $labal и eval! Вы должны чувствовать себя очень странно глубоко внутри себя, когда вы видите это! (это мой случай). Вот почему я добавил комментарий. Так что позже я пойму, что все в порядке.


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

$ ln -s . wtf
$ rm_where_this_points_to wtf
Oh dear, `wtf' points here exactly.
$ # Good :) but look:
$ cd wtf
$ rm_where_this_points_to wtf
$ # Oh, it did it! :(

Чтобы исправить это, нам понадобится разархивировать PWD, экранировать его с помощью printf '%q' и сравните это с разыменованным и экранированным элементом, который мы хотим удалить. Это только сделает код немного более сложным:

rm_where_this_points_to() {
    local labas=$( cd -P -- "$1" && printf '%q' "$PWD" )
    local ici=$( cd -P . && printf '%q' "$PWD" )
    [[ -z "$labas" ]] && { echo >&2 "Couldn't go where \`$1' points to."; return 1; }
    [[ -z "$ici" ]] && { echo >&2 "Something really weird happened: I can't dereference the current directory."; return 1; }
    if [[ "$labas" = "$ici" ]]; then
        echo >&2 "Oh dear, \`$1' points here exactly."
        return 1
    fi
    # eval and unquoted $labas, I know what I'm doing:
    # $labas has been sanitized and comes directly from `printf '%q'`
    eval "rm -rfv -- $labas"
}

( ici означает здесь по-французски).

Эту функцию я бы использовал (пока я не обнаружу, что у нее все еще есть некоторые недостатки ... если вы обнаружите их, сообщите мне об этом в комментариях).


Я уже говорил, что классным решением было бы cd -P каталог, который я хочу удалить, и удалить его оттуда, используя rm -rf ., но это не работает. Ну, действительно грязный метод был бы вместо rm -rf -- "$PWD". Это ужасно грязно, но очень весело:

rm_where_this_points_to_dirty() {
    ( cd -P -- "$1" && rm -rfv -- "$PWD" )
}

Готово!

Используйте на свой страх и риск !!!

Приветствия!


В этом посте вы могли бы выучить одно из следующего:

  • Чтобы использовать больше цитат!
  • Чтобы использовать больше цитат!
  • cd -P против [Тысяча сто семьдесят шесть]. [Тысяча сто девяносто-семь]
  • , что завершающий перевод строки может иметь катастрофические последствия при использовании подстановки команд , то есть $(...).
  • Переменные PWD и OLDPWD.
  • Чтобы использовать , чтобы получить крутые эффекты.
  • printf и его модификатор %q.
  • Использовать --.
  • Подоболочки.
  • Как сказать там и здесь по-французски.
  • Никогда не использовать eval. Никогда.
...', чтобы получить крутые эффекты.
  • printf и его модификатор %q.
  • Использовать --.
  • Подоболочки.
  • Как сказать там и здесь по-французски.
  • Никогда не использовать eval. Никогда.
  • a dir with a trailing newline\n' $ # :)

    ( l & agrave; -bas означает там по-французски).

    11139 Но что мы будем делать с этой глупой нитью? Полегче, будем использовать страшное, зло eval. Действительно, никогда, никогда, никогда не используйте eval. Это плохо. Бог убивает котенка каждый раз, когда вы используете eval. Действительно, поверь мне. Если, конечно, вы точно не знаете, что делаете. Если вы не уверены, что ваши данные были очищены. (Вы знаете Бобби Таблицы?). Но здесь, это так. Модификатор printf %q просто делает это для нас! Тогда:

    rm_where_this_points_to() {
        local labas=$( cd -P -- "$1" && printf '%q' "$PWD" )
        [[ -z "$labas" ]] && { echo >&2 "Couldn't go where \`$1' points to."; return 1; }
        if [[ "$labas" = "$(printf '%q' "$PWD")" ]]; then
            echo >&2 "Oh dear, \`$1' points here exactly."
            return 1
        fi
        # eval and unquoted $labas, I know what I'm doing:
        # $labas has been sanitized and comes directly from `printf '%q'`
        eval "rm -rfv -- $labas"
    }
    

    Смотри, здесь есть кавычки $labal и eval! Вы должны чувствовать себя очень странно глубоко внутри себя, когда вы видите это! (это мой случай). Вот почему я добавил комментарий. Так что позже я пойму, что все в порядке.


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

    $ ln -s . wtf
    $ rm_where_this_points_to wtf
    Oh dear, `wtf' points here exactly.
    $ # Good :) but look:
    $ cd wtf
    $ rm_where_this_points_to wtf
    $ # Oh, it did it! :(
    

    Чтобы исправить это, нам понадобится разархивировать PWD, экранировать его с помощью printf '%q' и сравните это с разыменованным и экранированным элементом, который мы хотим удалить. Это только сделает код немного более сложным:

    rm_where_this_points_to() {
        local labas=$( cd -P -- "$1" && printf '%q' "$PWD" )
        local ici=$( cd -P . && printf '%q' "$PWD" )
        [[ -z "$labas" ]] && { echo >&2 "Couldn't go where \`$1' points to."; return 1; }
        [[ -z "$ici" ]] && { echo >&2 "Something really weird happened: I can't dereference the current directory."; return 1; }
        if [[ "$labas" = "$ici" ]]; then
            echo >&2 "Oh dear, \`$1' points here exactly."
            return 1
        fi
        # eval and unquoted $labas, I know what I'm doing:
        # $labas has been sanitized and comes directly from `printf '%q'`
        eval "rm -rfv -- $labas"
    }
    

    ( ici означает здесь по-французски).

    Эту функцию я бы использовал (пока я не обнаружу, что у нее все еще есть некоторые недостатки ... если вы обнаружите их, сообщите мне об этом в комментариях).


    Я уже говорил, что классным решением было бы cd -P каталог, который я хочу удалить, и удалить его оттуда, используя rm -rf ., но это не работает. Ну, действительно грязный метод был бы вместо rm -rf -- "$PWD". Это ужасно грязно, но очень весело:

    rm_where_this_points_to_dirty() {
        ( cd -P -- "$1" && rm -rfv -- "$PWD" )
    }
    

    Готово!

    Используйте на свой страх и риск !!!

    Приветствия!


    В этом посте вы могли бы выучить одно из следующего:

    • Чтобы использовать больше цитат!
    • Чтобы использовать больше цитат!
    • cd -P против [Тысяча сто семьдесят шесть]. [Тысяча сто девяносто-семь]
    • , что завершающий перевод строки может иметь катастрофические последствия при использовании подстановки команд , то есть $(...).
    • Переменные PWD и OLDPWD.
    • Чтобы использовать , чтобы получить крутые эффекты.
    • printf и его модификатор %q.
    • Использовать --.
    • Подоболочки.
    • Как сказать там и здесь по-французски.
    • Никогда не использовать eval. Никогда.
    ...', чтобы получить крутые эффекты.
  • printf и его модификатор %q.
  • Использовать --.
  • Подоболочки.
  • Как сказать там и здесь по-французски.
  • Никогда не использовать eval. Никогда.
  • a dir with a trailing newline\n' $ # :)

    Теперь, можем ли мы поместить stdout подоболочки в переменную? Конечно, просто добавьте подоболочку с помощью $:

    $ labas=$(cd test; printf '%q' "$PWD")
    $ echo "$labas"
     

    ( l & agrave; -bas означает там по-французски).

    11139 Но что мы будем делать с этой глупой нитью? Полегче, будем использовать страшное, зло eval. Действительно, никогда, никогда, никогда не используйте eval. Это плохо. Бог убивает котенка каждый раз, когда вы используете eval. Действительно, поверь мне. Если, конечно, вы точно не знаете, что делаете. Если вы не уверены, что ваши данные были очищены. (Вы знаете Бобби Таблицы?). Но здесь, это так. Модификатор printf %q просто делает это для нас! Тогда:

    rm_where_this_points_to() {
        local labas=$( cd -P -- "$1" && printf '%q' "$PWD" )
        [[ -z "$labas" ]] && { echo >&2 "Couldn't go where \`$1' points to."; return 1; }
        if [[ "$labas" = "$(printf '%q' "$PWD")" ]]; then
            echo >&2 "Oh dear, \`$1' points here exactly."
            return 1
        fi
        # eval and unquoted $labas, I know what I'm doing:
        # $labas has been sanitized and comes directly from `printf '%q'`
        eval "rm -rfv -- $labas"
    }
    

    Смотри, здесь есть кавычки $labal и eval! Вы должны чувствовать себя очень странно глубоко внутри себя, когда вы видите это! (это мой случай). Вот почему я добавил комментарий. Так что позже я пойму, что все в порядке.


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

    $ ln -s . wtf
    $ rm_where_this_points_to wtf
    Oh dear, `wtf' points here exactly.
    $ # Good :) but look:
    $ cd wtf
    $ rm_where_this_points_to wtf
    $ # Oh, it did it! :(
    

    Чтобы исправить это, нам понадобится разархивировать PWD, экранировать его с помощью printf '%q' и сравните это с разыменованным и экранированным элементом, который мы хотим удалить. Это только сделает код немного более сложным:

    rm_where_this_points_to() {
        local labas=$( cd -P -- "$1" && printf '%q' "$PWD" )
        local ici=$( cd -P . && printf '%q' "$PWD" )
        [[ -z "$labas" ]] && { echo >&2 "Couldn't go where \`$1' points to."; return 1; }
        [[ -z "$ici" ]] && { echo >&2 "Something really weird happened: I can't dereference the current directory."; return 1; }
        if [[ "$labas" = "$ici" ]]; then
            echo >&2 "Oh dear, \`$1' points here exactly."
            return 1
        fi
        # eval and unquoted $labas, I know what I'm doing:
        # $labas has been sanitized and comes directly from `printf '%q'`
        eval "rm -rfv -- $labas"
    }
    

    ( ici означает здесь по-французски).

    Эту функцию я бы использовал (пока я не обнаружу, что у нее все еще есть некоторые недостатки ... если вы обнаружите их, сообщите мне об этом в комментариях).


    Я уже говорил, что классным решением было бы cd -P каталог, который я хочу удалить, и удалить его оттуда, используя rm -rf ., но это не работает. Ну, действительно грязный метод был бы вместо rm -rf -- "$PWD". Это ужасно грязно, но очень весело:

    rm_where_this_points_to_dirty() {
        ( cd -P -- "$1" && rm -rfv -- "$PWD" )
    }
    

    Готово!

    Используйте на свой страх и риск !!!

    Приветствия!


    В этом посте вы могли бы выучить одно из следующего:

    • Чтобы использовать больше цитат!
    • Чтобы использовать больше цитат!
    • cd -P против [Тысяча сто семьдесят шесть]. [Тысяча сто девяносто-семь]
    • , что завершающий перевод строки может иметь катастрофические последствия при использовании подстановки команд , то есть $(...).
    • Переменные PWD и OLDPWD.
    • Чтобы использовать , чтобы получить крутые эффекты.
    • printf и его модификатор %q.
    • Использовать --.
    • Подоболочки.
    • Как сказать там и здесь по-французски.
    • Никогда не использовать eval. Никогда.
    ...', чтобы получить крутые эффекты.
  • printf и его модификатор %q.
  • Использовать --.
  • Подоболочки.
  • Как сказать там и здесь по-французски.
  • Никогда не использовать eval. Никогда.
  • a dir with a trailing newline\n' $ # :)

    ( l & agrave; -bas означает там по-французски).

    11139 Но что мы будем делать с этой глупой нитью? Полегче, будем использовать страшное, зло eval. Действительно, никогда, никогда, никогда не используйте eval. Это плохо. Бог убивает котенка каждый раз, когда вы используете eval. Действительно, поверь мне. Если, конечно, вы точно не знаете, что делаете. Если вы не уверены, что ваши данные были очищены. (Вы знаете Бобби Таблицы?). Но здесь, это так. Модификатор printf %q просто делает это для нас! Тогда:

    rm_where_this_points_to() {
        local labas=$( cd -P -- "$1" && printf '%q' "$PWD" )
        [[ -z "$labas" ]] && { echo >&2 "Couldn't go where \`$1' points to."; return 1; }
        if [[ "$labas" = "$(printf '%q' "$PWD")" ]]; then
            echo >&2 "Oh dear, \`$1' points here exactly."
            return 1
        fi
        # eval and unquoted $labas, I know what I'm doing:
        # $labas has been sanitized and comes directly from `printf '%q'`
        eval "rm -rfv -- $labas"
    }
    

    Смотри, здесь есть кавычки $labal и eval! Вы должны чувствовать себя очень странно глубоко внутри себя, когда вы видите это! (это мой случай). Вот почему я добавил комментарий. Так что позже я пойму, что все в порядке.


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

    $ ln -s . wtf
    $ rm_where_this_points_to wtf
    Oh dear, `wtf' points here exactly.
    $ # Good :) but look:
    $ cd wtf
    $ rm_where_this_points_to wtf
    $ # Oh, it did it! :(
    

    Чтобы исправить это, нам понадобится разархивировать PWD, экранировать его с помощью printf '%q' и сравните это с разыменованным и экранированным элементом, который мы хотим удалить. Это только сделает код немного более сложным:

    rm_where_this_points_to() {
        local labas=$( cd -P -- "$1" && printf '%q' "$PWD" )
        local ici=$( cd -P . && printf '%q' "$PWD" )
        [[ -z "$labas" ]] && { echo >&2 "Couldn't go where \`$1' points to."; return 1; }
        [[ -z "$ici" ]] && { echo >&2 "Something really weird happened: I can't dereference the current directory."; return 1; }
        if [[ "$labas" = "$ici" ]]; then
            echo >&2 "Oh dear, \`$1' points here exactly."
            return 1
        fi
        # eval and unquoted $labas, I know what I'm doing:
        # $labas has been sanitized and comes directly from `printf '%q'`
        eval "rm -rfv -- $labas"
    }
    

    ( ici означает здесь по-французски).

    Эту функцию я бы использовал (пока я не обнаружу, что у нее все еще есть некоторые недостатки ... если вы обнаружите их, сообщите мне об этом в комментариях).


    Я уже говорил, что классным решением было бы cd -P каталог, который я хочу удалить, и удалить его оттуда, используя rm -rf ., но это не работает. Ну, действительно грязный метод был бы вместо rm -rf -- "$PWD". Это ужасно грязно, но очень весело:

    rm_where_this_points_to_dirty() {
        ( cd -P -- "$1" && rm -rfv -- "$PWD" )
    }
    

    Готово!

    Используйте на свой страх и риск !!!

    Приветствия!


    В этом посте вы могли бы выучить одно из следующего:

    • Чтобы использовать больше цитат!
    • Чтобы использовать больше цитат!
    • cd -P против [Тысяча сто семьдесят шесть]. [Тысяча сто девяносто-семь]
    • , что завершающий перевод строки может иметь катастрофические последствия при использовании подстановки команд , то есть $(...).
    • Переменные PWD и OLDPWD.
    • Чтобы использовать , чтобы получить крутые эффекты.
    • printf и его модификатор %q.
    • Использовать --.
    • Подоболочки.
    • Как сказать там и здесь по-французски.
    • Никогда не использовать eval. Никогда.
    ...', чтобы получить крутые эффекты.
  • printf и его модификатор %q.
  • Использовать --.
  • Подоболочки.
  • Как сказать там и здесь по-французски.
  • Никогда не использовать eval. Никогда.
  • 0
    ответ дан 5 November 2013 в 23:03

    Другие вопросы по тегам:

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