find в наборе каталогов, которые могут не существовать

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

getent passwd username | cut -d: -f6

(где username Ваше имя пользователя). Я предположил бы, что это будет что-то как /home/username. Это может быть /home3/username в этом случае необходимо установить корневой каталог с:

usermod -d /home2/username username

(необходимо будет выполнить это как пользователь root или использование sudo для выполнения его как корня, если у Вас есть доступ в sudoers файле):

sudo usermod -d /home2/username username

Если вышеупомянутое не имеет место, и если getent команда возвратила Ваш корневой каталог как /home, необходимо видеть если /home уже символьная ссылка:

ls -ld /home

Если вывод имеет форму (показывая ту из символьной ссылки, и это решает к home3):

lrwxr-xr-x  1 root  root  4 Aug 29 13:37 home@ -> home3

Затем уже существует символьная ссылка, которая указывает на home3, и необходимо изменить это.

rm /home ; ln -sf /home2 /home3

Относительно диагностирования проблемы, если у Вас есть доступ к корневой учетной записи, проверка ~root/.bash_history файл, поскольку я предположил бы, что пользователь изменил пути. Можно также хотеть уничтожить ту сессию входа в систему путем издания:

ps ua | grep '[p]ts/5'

Вы должны быть произведены, который смотрит что-то как:

root    19687  0.0  0.1  26896  9732 pts/5    Ss+  Aug20   0:00 -bash

и затем можно завершить сессию путем передачи связанного идентификатора процесса (2-й столбец от вывода команды PS) к kill команда:

kill -15 19687

Предоставление корневого доступа удаленно является, как правило, очень плохой практикой. Рекомендуется использовать некорневую учетную запись и sudo для получения корневого доступа от удаленных хостов. Также выставляя корневую учетную запись и установку PasswordAuthentication yes действительно плохая практика, особенно если у Вас есть слабый пароль, поскольку это может быть грубо вызванный и Ваш поставленный под угрозу хост (как это, возможно, произошло с Вами здесь).

Если у Вас есть некорневая учетная запись с удаленным доступом к хосту и полномочиям в sudo для выполнения всех команд как корня, я также рекомендовал бы изменить пароль root, sudo passwd и изменение /etc/ssh/sshd_config иметь установку PermitRootLogin no, таким образом, удаленные хосты не могут соединиться как пользователь root. Необходимо будет перезапустить sshd, если это установлено с:

/etc/init.d/sshd restart

(который может быть /etc/init.d/ssh restart в зависимости от Вашей ОС). В будущем, если Вы нуждаетесь в корневой оболочке, ssh к хосту как Ваш некорневой пользователь, и работаете exec sudo bash получить корневую оболочку.

3
29.05.2015, 23:51
4 ответа

Если это работает для вас

найти $ (пути) -type f name foo.sh

, то вы можете изменить функцию путей на эхо только допустимые пути, как

if [ -d "$path" ]; then echo $path fi

или если путь может быть также

if [ -d "$path" ] || [ -e "$path" ]; then echo $path fi

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

-121--105341-

Можно проверить существование пути с помощью python, повторить пути, найденные при разделении NUL, и передать их в xargs для передачи find , если только длина вывода python не превышает максимальную длину аргумента, который должен вызывать поиск только один раз:

python -c 'import os, sys;  sys.stdout.write("\0".join([x for x in sys.argv[1:] if os.path.exists(x)]) + "\0")' a\ b xyz abc| xargs -0 --no-run-if-empty find

Часть python (одиночный приведенный аргумент -c):

  • импортирует необходимые модули os и sys , используемые в команде
  • , над аргументами a b , xyz и abc , используя для x в sys.argv [1:]
  • помещает в список только в том случае, если путь существует: [x... если os.path.exists (x)]
  • соединяет список с NUL и добавляет NUL и записывает его в stdout: sys.stdout.write («\0 ». join [...] + «\0»)

Если у вас есть пустой каталог и вы коснетесь a\b xyz , вы увидите, что первые два аргумента найдены, но abc отсутствует, а поиск никогда не передается по последнему пути.

-121--105340-

В zsh , если в массиве имеются пути, как в:

files=($(paths))

(который будет разделять выходные данные путей в пространстве, новой строке табуляции или нуле) или:

files=(${(f)"$(paths)"})

, чтобы разделить строки, можно сделать:

find $^files(N) -type f -name foo.sh

Или если вы хотите ограничить каталоги:

find $^files(/N) -type f -name foo.sh

Теперь, если ни один из этих файлов не существует, вы можете работать:

find -type f -name foo.sh

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

dirs=($^files(/N))
(($#dirs)) && find $dirs -type f -name foo.sh

Или:

setopt cshnullglob
find $^files(/) -type f -name foo.sh

Теперь, с zsh , нет реальной необходимости найти здесь, вы могли бы просто сделать:

files=($^files/**/foo.sh(.N))

Это также было бы полезно, даже если эти файлы, как ! или - имя , которое найдет .

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

3
27.01.2020, 21:19

Поскольку вы используете Bash, храните список путей в массиве . Итайте для массива, чтобы построить массив существующих путей. Вам нужен особый случай, если результирующий массив пуст, как Найти , будет либо ошибся или пройти текущий каталог.

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

paths=(/some/where around/here -print 'one  with
odd spaces')
existing_paths=()
for x in "${paths[@]}"; do
  if [ -e "$x" ]; then
    if [[ "$x" = -* ]]; then x="./$x";; fi
    existing_paths+=("$x")
  fi
done
if [[ ${#existing_paths[@]} -ne 0 ]]; then
  find "${existing_paths[@]}" -type f -name foo.sh
fi
1
27.01.2020, 21:19

Если это работает для вас

, найдут $ (PATTORS) -TYPE f имя foo.sh

, то вы можете изменить функцию путей для эха, только действительные пути, такие как

if [ -d "$path" ]; then echo $path fi

или если Путь тоже может быть файлом

if [ -d "$path" ] || [ -e "$path" ]; then echo $path fi

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

0
27.01.2020, 21:19

Вы можете проверить наличие пути с помощью python, повторить пути, найденные с разделением NUL, и передать их в xargs для передачи на find , если длина вывода python не превышает максимальную длину аргумента, который должен вызывать find только один раз:

python -c 'import os, sys;  sys.stdout.write("\0".join([x for x in sys.argv[1:] if os.path.exists(x)]) + "\0")' a\ b xyz abc| xargs -0 --no-run-if-empty find

Часть python (аргумент в одиночных кавычках для -c):

  • импортирует необходимые модули os и sys , используемые в команде
  • , обходят аргументы ab , xyz и abc ] с использованием для x в sys.argv [1:]
  • помещается в список, только если путь существует: [x ... if os.path.exists (x)]
  • присоединяется к списку с помощью NUL и добавляет NUL и записывает это в стандартный вывод: sys.stdout.write ("\ 0" .join [...] + "\ 0")

Если у вас пустой каталог и вы нажмете на \ b xyz , вы увидите, что первые два аргумента найдены, но abc - нет и найти никогда не передается последний путь.

0
27.01.2020, 21:19

Теги

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