Вероятно, лучшим инструментом для работы с изображениями будет ImageMagick. Если вы посмотрите документацию, там есть обширные примеры, показывающие, как использовать функцию -distort
, которую, как мне кажется, вы ищете.
До После
Командная строка для выполнения преобразования:
$ convert checks.png -filter point
-virtual-pixel tile -mattecolor DodgerBlue
-distort Perspective '0,0 20,60 90,0 70,63 0,90 5,83 90,90 85,88'
horizon_tile_point.png
Есть 2 другие методы выполнения выборки, чтобы изображение выглядело лучше. В частности, "суперсэмплинг сетки" и "повторная выборка эллиптической взвешенной области (EWA)". Последний вариант используется по умолчанию.
Есть 2 ресурса для понимания того, как сгенерировать серию координат для преобразовать
. Первый - это тот, который я дал выше. Второй - это SO Q&A под названием: Понимание искажения перспективной проекции ImageMagick , в частности, @ KurtPfeifle, ответ .
Координаты следующие:
Sx1,Sy1 Dx1,Dy1 Sx2,Sy2 Dx2,Dy2 Sx3,Sy3 Dx3,Dy3 ... Sxn,Syn Dxn,Dyn
После внесения предложенных изменений, если найти два способа добиться моего результата.
Первое решение:Использование цикла for
#!/bin/bash/expect
DATE=`date "+%d-%m-%Y_%H-%M-%S"`
for i in `cat /root/project_finduser/serverlist`;
do
echo -e "\n*******************"
echo -e "$i"
for a in `cat /root/project_finduser/userslist`;
do
echo -e "\n"
echo -n "$a :"
if ssh "root@${i}" cat /etc/passwd | grep -w -q -F -e "$a";
then
echo "User exsits"
else
echo "User not exsits"
fi
done
done >>"/tmp/userfind_${DATE}.txt"
Второе решение:Использование цикла While { Я передал -параметр n с помощью команды ssh, потому что в то время как цикл прекращает чтение аргумента из файла после первой строки}
#!/bin/bash
DATE=`date "+%d-%m-%Y_%H-%M-%S"`
while IFS= read -r ipaddress;
do
echo -e "\n*******************"
echo -e "$ipaddress"
while IFS= read -r userid;
do
echo -e "\n"
echo -n "$userid : "
if ssh -n "root@${ipaddress}" getent passwd "$userid" >/dev/null;
then
echo -n "User exsits"
else
echo -n "User not exsits"
fi
done < /root/project_finduser/userslist
done < /root/project_finduser/serverlist >"/tmp/userfind_${DATE}.txt"
Выход:
192.168.56.103
sandeep :Выход пользователя
студент :Пользователь уходит
ram :Пользователь не выходит
sita :Пользователь не выходит
swati :Выход пользователя
студент :Пользователь уходит
192.168.56.104
sandeep :Пользователь не выходит
студент :Пользователь уходит
ram :Пользователь не выходит
sita :Пользователь не выходит
swati :Пользователь не выходит
студент :Пользователь уходит
Основная проблема в вашем коде заключается в том, что $?
раскрывается перед вызовом ssh
. Это из-за цитирования. Все расширения в строке с двойными -кавычками раскрываются перед использованием строки. Кроме того, строка в двойных -кавычках, которую вы используете с ssh
, содержит другие разделы в двойных -кавычках. Эти разделы будут без кавычек , точно так же, как подстрока abc
не заключена в кавычки в "123"abc"456"
.
Вместо того, чтобы пытаться выполнить сложную команду на удаленном хосте, просто дайте ssh
команду cat
файлу passwd
, затем grep
этому:
if ssh -n "sandeep@$ipaddress" cat /etc/passwd | grep -q -F -e "$userid"
then
echo "User exists"
else
echo "User does not exist"
fi >>"/tmp/userfind_$DATE.txt"
Кроме того, рассмотрите возможность чтения из списка пользователей и серверов с использованием вместо этого цикла while:
while IFS= read -r userid; do
#...
done </home/sandeep/Project_finduser01/userslist
Вы также можете перенаправить самый внешний цикл в выходной файл вместо перенаправления каждого отдельного цикла.echo
:
while...; do
while...; do
# stuff
done <userlist
done <serverlist >"/tmp/userfind_$DATE.txt"
Если ваш список пользователей длинный, вы можете получить passwd
с удаленного хоста только один раз, а затем запросить его несколько раз
while...; do
scp "sandeep@$ipaddress:/etc/passwd" passwd.tmp
while...; do
if grep -q -F -e "$userid" passwd.tmp; then
# exists
fi
done <userlist
done <serverlist >"/tmp/userfind_$DATE.txt"
Еще эффективнее было бы прочитать список пользователей в массив awk
и затем сопоставить с ними имена пользователей из файла passwd
. Это позволит полностью избавиться от самого внутреннего цикла.
Имя пользователя находится в определенном поле в файле passwd
. С вашим подходом вы найдете как marc
, так и marco
, если будете искать marc
. Для более тщательного сопоставления рассмотрите возможность использования шаблона, такого как "^$userid:"
, вместо сопоставления всей строки (и отбросьте -F
, который я представил выше, если вы все еще используете grep
для этого ). ].
Вы также можете полностью избежать разбора файла passwd
с помощью
getent passwd "$userid" >/dev/null
Это возвращает нулевой код выхода (успех ), если пользователь существует, и не -ноль в противном случае.
То есть,
if ssh -n "sandeep@$ipaddress" getent passwd "$userid" >/dev/null
then
# exists
else
# does not exist
fi
Тем не менее, это будет выполнять один ssh
вызов удаленного хоста для каждого пользователя. Это можно сделать немного эффективнее, если не закрывать соединение между каждым вызовом (, как показано ниже, соединение будет оставаться открытым в течение одной минуты):
if ssh -n -o ControlMaster=auto -o ControlPersist=1m "sandeep@$ipaddress" getent passwd "$userid" >/dev/null
then
# exists
else
# does not exist
fi
Почему бы не записать код результата из $?
вот так…
ssh user@host 'cmd arg;echo $?'
Если вы присвоите это значение переменной, вы сможете применить к ней [ $n -gt 0 ]
тест.