Сценарий Bash для перезаписывания / добавления файла назначения с помощью меню опций [duplicate]

Это работает для меня. Откройте терминал & amp; выполните эту команду.

killall nautilus

Это будет полезно. Спасибо.

-2
задан 24 April 2018 в 06:33

2 ответа

Как вы заявили, проблема, которую вы пытаетесь решить, - это (выделено мной):

Я пытаюсь написать сценарий bash, чтобы пригласить пользователя для имени файла, и если файл существует, позволяет им перезаписывать или добавлять файл.

Любопытно, что код в вашем скрипте, который проверяет, существует ли файл, не использует if, хотя он, вероятно, должен. Вместо этого он использует while:

while [ -e "$sourceFile" ]; do

Это цикл. Если исходный файл существует, все внутри этого цикла выполняется до соответствия

done

в последней строке вашего скрипта. Это цикл while, поэтому после его запуска первый раз снова выполняется тест. Если файл все еще существует, тело цикла запускается снова и т. Д. И т. Д. И т. Д.

Но ничто в теле цикла никогда не останавливает существующий файл. Четыре возможности:

Пользователь вводит 1, а исходный файл копируется по целевому файлу. Он копируется, не перемещается, поэтому исходный файл все еще существует с тем же именем. Пользователь вводит 2, а содержимое исходного файла добавляется к целевому файлу. Однако исходный файл не удаляется; он все еще там. Пользователь вводит сообщение 3 и печатается сообщение Script Terminated. За этим сразу следует команда break. Это вырывается из конструкции select. В сводке break, которую вы получаете, когда вы запускаете help break, только упоминается, что она вырывается из циклов for, while или until, поэтому, возможно, вы ожидали, что она нарушит внешний цикл while. Однако резюме select, которое вы получаете при запуске help select, разъясняет вопрос: COMMANDS выполняются после каждого выбора до тех пор, пока не будет выполнена команда break. Пользователь вводит ничего, кроме 1, 2 или 3. Таким образом, ни один из случаев не работает. Выполняется вторая команда break после esac. Это также разрушает конструкцию select, а не цикл while, поэтому цикл while запускается снова.

select - фактически цикл. Ваши команды break ломают select, а не внешние while. Учитывая описанное описание проблемы, вы почти наверняка не имеете никаких оснований использовать внешний цикл. Поэтому одним хорошим решением было бы изменить внешний while на if. Для этого вам также понадобится:

Измените его do на then. Измените его done на fi.

Если вы выберете это решение, вы также захотите переместить некоторые из команд, которые у вас есть за пределами while (который должен быть if), чтобы они находились внутри него. Прямо сейчас пользователю предлагается выбрать вариант, даже если никакое действие не будет принято. Эта дополнительная ошибка не будет исправлена, просто изменив значение while на if (и сделав два других необходимых изменения для этого).

Альтернативное решение - сделать ваш скрипт более ранним, если [ -e "$sourceFile" ] неверно. Один из способов сделать это:

[ -e "$sourceFile" ] || exit

Другой, если вы предпочитаете использовать if, это:

if ! [ -e "$sourceFile" ]; then exit fi

Если вы используете любой из них, то остальные кода - код, который вы собираетесь запускать только в том случае, если существует исходный файл, - не нужно будет вставлять в вне структуры управления . Обратите внимание, что вы по-прежнему хотите, чтобы это произошло раньше, а не после, команд, которые запрашивают у пользователя какие действия предпринять.

Обратите внимание, что вы можете «исправить» ваш код, заменив команды break с exit. Вы также можете «исправить» его, передав числовой аргумент break, чтобы рассказать ему, сколько уровней гнездования вырваться из (команды большинства языков break не поддерживают это, но Bash's does). Тем не менее, я рекомендую не использовать любой из этих подходов - за исключением, возможно, просто попробовать это, потому что вы добавляете больше сложности в код, который вместо этого должен быть исправлен, упрощая его. Итак, одним хорошим решением было бы изменить внешний while на if. , поэтому, тем не менее, вы решаете проблему, это должно быть таким образом, чтобы упростить код, делая это.

Если, с другой стороны, вы действительно намереваетесь, чтобы все это повторялось снова и снова, тогда вы должны рассмотреть, какое условие значимо нарушит ваш внешний цикл. Например, возможно, вы хотели запросить исходные и целевые файлы в каждой итерации внешнего цикла. Если это так, вам нужно будет изменить свой код, чтобы это сделать.

Наконец, я рекомендую отступывать свой код таким образом, что, когда структура управления охватывает несколько строк, строка, которая открывает ее и строка, которая закрывает его, имеет отступы на том же уровне, и строки внутри него (за исключением случайных ситуаций, когда это невозможно сделать) больше отступают. Таким образом, вы узнаете, какой fi соответствует if, который done соответствует while / until / for / select, и который esac соответствует тому, что case. Благодаря тому, что легче распознать это, вы также сможете лучше идентифицировать, когда нужное ключевое слово может , и путем отступов содержимого в согласованном виде вы сможете лучше идентифицировать когда логика, если ваш сценарий отличается от того, что вы намереваетесь.

4
ответ дан 17 July 2018 в 16:17

Как вы заявили, проблема, которую вы пытаетесь решить, - это (выделено мной):

Я пытаюсь написать сценарий bash, чтобы пригласить пользователя для имени файла, и если файл существует, позволяет им перезаписывать или добавлять файл.

Любопытно, что код в вашем скрипте, который проверяет, существует ли файл, не использует if, хотя он, вероятно, должен. Вместо этого он использует while:

while [ -e "$sourceFile" ]; do

Это цикл. Если исходный файл существует, все внутри этого цикла выполняется до соответствия

done

в последней строке вашего скрипта. Это цикл while, поэтому после его запуска первый раз снова выполняется тест. Если файл все еще существует, тело цикла запускается снова и т. Д. И т. Д. И т. Д.

Но ничто в теле цикла никогда не останавливает существующий файл. Четыре возможности:

Пользователь вводит 1, а исходный файл копируется по целевому файлу. Он копируется, не перемещается, поэтому исходный файл все еще существует с тем же именем. Пользователь вводит 2, а содержимое исходного файла добавляется к целевому файлу. Однако исходный файл не удаляется; он все еще там. Пользователь вводит сообщение 3 и печатается сообщение Script Terminated. За этим сразу следует команда break. Это вырывается из конструкции select. В сводке break, которую вы получаете, когда вы запускаете help break, только упоминается, что она вырывается из циклов for, while или until, поэтому, возможно, вы ожидали, что она нарушит внешний цикл while. Однако резюме select, которое вы получаете при запуске help select, разъясняет вопрос: COMMANDS выполняются после каждого выбора до тех пор, пока не будет выполнена команда break. Пользователь вводит ничего, кроме 1, 2 или 3. Таким образом, ни один из случаев не работает. Выполняется вторая команда break после esac. Это также разрушает конструкцию select, а не цикл while, поэтому цикл while запускается снова.

select - фактически цикл. Ваши команды break ломают select, а не внешние while. Учитывая описанное описание проблемы, вы почти наверняка не имеете никаких оснований использовать внешний цикл. Поэтому одним хорошим решением было бы изменить внешний while на if. Для этого вам также понадобится:

Измените его do на then. Измените его done на fi.

Если вы выберете это решение, вы также захотите переместить некоторые из команд, которые у вас есть за пределами while (который должен быть if), чтобы они находились внутри него. Прямо сейчас пользователю предлагается выбрать вариант, даже если никакое действие не будет принято. Эта дополнительная ошибка не будет исправлена, просто изменив значение while на if (и сделав два других необходимых изменения для этого).

Альтернативное решение - сделать ваш скрипт более ранним, если [ -e "$sourceFile" ] неверно. Один из способов сделать это:

[ -e "$sourceFile" ] || exit

Другой, если вы предпочитаете использовать if, это:

if ! [ -e "$sourceFile" ]; then exit fi

Если вы используете любой из них, то остальные кода - код, который вы собираетесь запускать только в том случае, если существует исходный файл, - не нужно будет вставлять в вне структуры управления . Обратите внимание, что вы по-прежнему хотите, чтобы это произошло раньше, а не после, команд, которые запрашивают у пользователя какие действия предпринять.

Обратите внимание, что вы можете «исправить» ваш код, заменив команды break с exit. Вы также можете «исправить» его, передав числовой аргумент break, чтобы рассказать ему, сколько уровней гнездования вырваться из (команды большинства языков break не поддерживают это, но Bash's does). Тем не менее, я рекомендую не использовать любой из этих подходов - за исключением, возможно, просто попробовать это, потому что вы добавляете больше сложности в код, который вместо этого должен быть исправлен, упрощая его. Итак, одним хорошим решением было бы изменить внешний while на if. , поэтому, тем не менее, вы решаете проблему, это должно быть таким образом, чтобы упростить код, делая это.

Если, с другой стороны, вы действительно намереваетесь, чтобы все это повторялось снова и снова, тогда вы должны рассмотреть, какое условие значимо нарушит ваш внешний цикл. Например, возможно, вы хотели запросить исходные и целевые файлы в каждой итерации внешнего цикла. Если это так, вам нужно будет изменить свой код, чтобы это сделать.

Наконец, я рекомендую отступывать свой код таким образом, что, когда структура управления охватывает несколько строк, строка, которая открывает ее и строка, которая закрывает его, имеет отступы на том же уровне, и строки внутри него (за исключением случайных ситуаций, когда это невозможно сделать) больше отступают. Таким образом, вы узнаете, какой fi соответствует if, который done соответствует while / until / for / select, и который esac соответствует тому, что case. Благодаря тому, что легче распознать это, вы также сможете лучше идентифицировать, когда нужное ключевое слово может , и путем отступов содержимого в согласованном виде вы сможете лучше идентифицировать когда логика, если ваш сценарий отличается от того, что вы намереваетесь.

4
ответ дан 23 July 2018 в 17:11

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

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