Способ использования одной команды - удаление -тип
, из команды. Тогда мы получим:
find /var/www/html/*/dir0/dir1/ ! -name 'he_IL.mo' -exec rm -f {} +
Обратите внимание, что он не будет удалять каталоги и программные ссылки с именем he_IL.mo
, но если все в порядке, используйте его.
В этом скрипте всего несколько мелких ошибок, и я бы изменил несколько стилистических вещей. Давайте построчно пройдемся по оригиналу:
#!/bin/bash
port=$1
Типичный #!
и простое присваивание, у нас хорошее начало.
found=$(cat /etc/services | grep -o '[[:space:]]$port/' | wc -l)
В этой строке есть небольшая проблема, которую можно не заметить на первый взгляд. Поскольку $port
находится в сильных кавычках, '…$port'
, он не будет расширяться до своего значения. Вы можете использовать слабые кавычки вместо "…$port"
. Кроме того, здесь вам не нужен кошка
. grep
принимает имя файла в качестве аргумента, но если это не так, вы всегда можете использовать перенаправление (grep 'шаблон' < /etc/services
). Кроме того, grep -c
записывает количество совпадающих строк, поэтому wc -l
здесь также избыточен.
while [ $found -ge 1 ]; do
$port=$($port+1)
done
Цикл кажется почти в порядке. Вы захотите указать сущности в тесте на случай, если $found
может оказаться пустым. Кроме того, вы назначаете с помощью port=
, а не $port=
(но вы использовали правильную форму выше, поэтому я предполагаю, что это была просто опечатка). Наконец, $($port+1)
означает (например, если порт
равен 22
) «Вывод команды 22+1
".Очевидно, вам нужен «Результат арифметического выражения 22+1
», который очень похож на $(($port+1))
.
echo "found: $found"
echo "port: $port"
С этими строками все в порядке.
Теперь, если вы сделаете все вышеперечисленные изменения, чтобы программа стала синтаксически правильной, она все равно не будет делать то, что вы хотите. Вы не указали «правильный» вывод, поэтому я предполагаю, что вы хотите:
found: <the number of occurrences of $1 in /etc/services>
port: <the next free port>
Если эти предположения неверны, дайте мне знать в комментариях, и я отредактирую соответствующим образом.
Сценарий как есть никогда не вернется, если данный порт действительно появляется в /etc/services
, потому что вы никогда не обновляете found
. Таким образом, вы можете подумать, что было бы разумно скопировать строку found=…
в цикл, но это не так! Если вы это сделаете, то скрипт всегда будет возвращать found: 0
. Я думаю, что лучше всего здесь создать функцию:
found () {
grep -co "[[:space:]]$1/" /etc/services
}
, но теперь выходное значение этой функции может напрямую работать как условие. Вы захотите заглушить вывод, чтобы он не отображался вместе с вашим, и тогда вам больше не понадобятся флаги -co
, но вам понадобятся -q
:
while found "$port"; do
Затем, чтобы вернуть количество вхождений порта ввода, это будет
echo "found: $(found "$1")"
или вы можете использовать printf
.
Я думаю, что это сценарий, который вы пытались написать:
#!/bin/sh
found () {
grep -q "[[:space:]]$1/" /etc/services
}
port=$1
while found "$port"; do
port=$(($port+1))
done
printf 'found: %d\nport %d\n' "$(found "$1")" "$port"
Когда я писал это, моей первой реакцией было то, что подсчет строк, соответствующих заданному шаблону, может быть выполнен в awk
, а также grep
.Затем мне пришло в голову, что всю программу можно написать на awk
. В качестве бонуса вот одна из его реализаций (хотя здесь я предполагаю, что /etc/services
сортируется по номеру порта):
#!/usr/bin/awk -f
BEGIN {
FS = "[ \t/][ \t/]*"
ARGC = 2
PORT = ARGV[1]
OPORT = PORT
ARGV[1] = "/etc/services"
}
($2 == OPORT) {
FOUND = FOUND + 1
}
(NEXT == 0 && NR > 1 && $2 > PORT) {
NEXT = ($2 > PORT + 1) ? PORT + 1 : NEXT
PORT = $2
}
END {
printf "found: %d\nport: %d\n", FOUND, (FOUND == 0) ? OPORT : NEXT
}
За исключением математической части, вот быстрый и грязный POC для выполнения того, что вы собираетесь сделать, но с использованием оператора «if» вместо условий цикла «пока» для вашей логики.
#!/bin/bash
port=$1
echo $port | while read a; do
found=$(cat /etc/services | grep -Eo '[0-9]{1,5}/' | sed 's/^/ /' | grep ' '$a'/')
if [[ $found ]];
then echo port $a is being used
else echo port $a is not being used
fi
done
Редактировать: проблема возникла из-за переменной $found. одинарные кавычки в grep заставляют $port интерпретироваться буквально, поэтому он ищет строку Например, '$port/' вместо '80/'. исправить: просто измените одинарные кавычки на двойные кавычки.
found=$(cat /etc/services | grep -o "[[:space:]]$port/" | wc -l)