Создание версии скрипта оболочки команд терминала

Простая и компактная findкоманда для вашего случая может быть:

find.  -mindepth 2 -type f -name '*.ts' -exec fuser -s {} \; -a -exec mv /mnt/usbdrive {} \;

Здесь мы воспользовались возможностями выражения find:обратите внимание на оператор -a(, означающий «и» ), так что mvвыполняется, только если fuserзавершается с 0, значит файл открыт.

Это самая безопасная команда, способная работать с любыми символами, которые могут присутствовать в именах ваших файлов.

Но эта команда также может быть очень медленной, если в этом каталоге много файлов. На самом деле вы использовали синтаксис {} +вместе с опцией mv-t, чтобы облегчить это бремя.

К сожалению, мы не можем просто использовать этот синтаксис для двух -execдействий, потому что fuser выйдет с 0, когда любой из указанных файлов открыт, и мы даже не будем знать, какой файлы входят в число тех, которые предоставляются в качестве аргументов find.

Мы по-прежнему можем использовать синтаксис {} + и здесь, но нам нужна более сложная команда. Вот такой:

find. -mindepth 2 -type f -name '*.ts' -exec fuser {} + 2>&1 | sed 's/^\(.\+\):.*/\1/' | xargs mv -t /mnt/usbdrive

Разбивая то, что -execиспользует find, мы в основном имеем fuserрассмотрение всех файлов за один запуск, но также фильтруем его вывод через sed, чтобы получить только имена файлов(fuserвыводит PID вместе с именами файлов ), чтобы, наконец, направить их в xargs, выполняющую исходную команду mvза один раз. Для тестирования я бы рекомендовал добавить опцию -pк такому xargs, чтобы увидеть, что будет перемещено в случае подтверждения.

Затем я также заметил, что вы говорите, что хотели бы изменить разрешения и владельца помимо перемещения файла, только если он не открыт, но затем я вижу, что вы выполняете chownплюс chmodна весь каталог заранее. (В качестве примечания, chown 777вообще не имеет смысла, вы хотите поместить туда имя пользователя.. если только 777 действительно не является идентификатором пользователя -в вашей системе, но я сомневаюсь в этом ).

Итак, если вы хотите сделать то, что вы сказали, вы можете добавить эти команды в xargs, упаковав их в составную команду оболочки.

Вот так:

find. -mindepth 2 -type f -name '*.ts' -exec fuser {} + 2>&1 | sed -e 's/^\(.\+\):.*/\1/' | xargs sh -c 'echo sudo chmod 777 "${@}"; echo sudo chown user "${@}"; echo mv -t /mnt/usbdrive "${@}"' --

Это на самом деле только показывает команды, которые будут выполняться. Я бы порекомендовал поэкспериментировать с ним, и когда вы будете готовы действительно применить его, просто удалите echos.

Важное примечание:эти две последние команды, позволяющие использовать синтаксис find's {} +, не могут работать с именами файлов, содержащими встроенные символы новой строки из-за фильтрации, выполняемой sed. Работа с ними возможна, но будет еще сложнее из-за особого вывода fuser. Я думаю, разумно предположить, что ваши имена файлов не имеют встроенных символов новой строки, иначе вы можете использовать первую, более простую, но более медленную команду.

1
29.09.2020, 22:09
2 ответа

Все команды, которые вы вводите одну за другой в приглашении, можно просто поместить в файл сценария и выполнить один раз.

  1. Единственным требованием является строка интерпретатора, которая должна быть в начале файла

      #!/bin/sh
    

    вы можете написать скрипт для других, таких как bash(#!/bin/bash)или zsh(#!/bin/zsh)

  2. Сделайте ваш скрипт исполняемым, запустивchmod +x scriptFile.sh(расширение sh хорошо иметь, так как оно указывает, что это файл скрипта)

  3. Запустите скрипт, нажав

    ./scriptFile.sh

Дополнительно :Вы можете добавить путь к каталогу в переменную PATH, чтобы иметь возможность выполнять скрипт из любого каталога, просто вызвав scriptFile.shтак же, как вы вызываете любую другую команду оболочки lsилиcat

3
18.03.2021, 23:01

Использование текстового редактора для создания сценария

Скрипты сохраняются в текстовые файлы. Вы можете создать его в текстовом редакторе,например geditилиnano:

$ nano yourscript.sh

Имя файла вообще и расширение имени файла в частности не имеют значения . В вашем файле скрипта вы должны объявить исполняемый файл интерпретатора для его запуска (как shebang). Затем добавьте свой код. Чтобы сохранить сценарий в nano, нажмите Ctrl + X , затем введите yи нажмите Enter .

Составление сценария

Если вы передаете скрипту аргументы, вы можете ссылаться на них в своем коде по номеру (первый переданный аргумент — $1, второй — $2и так далее ). $0— это имя самого скрипта.

Как правило, переменные всегда заключаются в двойные кавычки .

Взяв ваш код, например, скрипт может быть:

#! /bin/bash
curl -O "$1"
head -n 12 cities.csv

После#!может быть пробел, но это не обязательно. В большинстве случаев вы можете проверить переменную $0в терминале для исполняемого файла оболочки , интерпретирующего ваши команды в терминале :

.
$ echo $0
/bin/bash

Улучшение вашего кода

Предполагая, что вам нужны только первые 12 строк загруженного файла, вы можете пропустить сохранение загруженного файла на диск и передать его следующей команде:

#! /bin/bash
curl -s "$1" | head -n 12

В качестве бонуса он позволяет вам не указывать имя файла в сценарии.

Запуск скрипта

Предполагая, что вы сохранили свой скрипт как yourscript.sh, сначала добавьте разрешение на его выполнение:

$ chmod +x yourscript.sh

Затем для его запуска нужно указать путь к нему и предоставить аргументы. Если он находится в текущем каталоге, вы можете указать путь к нему, добавив перед ним ./, например:

$./yourscript.sh 'https://people.sc.fsu.edu/~jburkardt/data/csv/cities.csv'
7
18.03.2021, 23:01

Теги

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