Почему бы просто не использовать su - gsxuserp -c "tail -f ../random_directory/file_in_random_directory"
?
Множественные su
не имеют смысла, потому что каждый из них начинает новую сессию, выполняет единственную команду, а затем закрывается. Последующие не помнят, в каком каталоге находились предыдущие, они каждый раз наследуют каталог вызывающего скрипта.
Полная команда будет такой (с учетом комментариев по поводу цитирования в другом ответе),
ssh -t user@something.com ssh -t cserver 'su - gsxuserp -c \"tail -f ../random_directory/file_in_random_directory\"'
Обратите внимание на использование одинарных и двойных кавычек (и экранированных двойных кавычек), а не просто серии двойных кавычек.
Простая и компактная 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 "${@}"' --
Это на самом деле только показывает команды, которые будут выполняться. Я бы порекомендовал поэкспериментировать с ним, и когда вы будете готовы действительно применить его, просто удалите echo
s.
Важное примечание:эти две последние команды, позволяющие использовать синтаксис find
's {} +
, не могут работать с именами файлов, содержащими встроенные символы новой строки из-за фильтрации, выполняемой sed
. Работа с ними возможна, но будет еще сложнее из-за особого вывода fuser
. Я думаю, разумно предположить, что ваши имена файлов не имеют встроенных символов новой строки, иначе вы можете использовать первую, более простую, но более медленную команду.