我正在尝试创建一个bash脚本,它可以在phpmyadmin命令文件中更改“allow from”ip地址(我仍然不确定是否可以这样做)并重新启动apache
我正在尝试从变量中提取IP地址,在搜索网络后我仍然没有任何线索,这是我到目前为止所拥有的...
#bash shell script
#!/bin/bash
clear
echo "Get client IP address"
ip=$(last -i)
echo $ip
exit
echo "restart apache"
/etc/init.d/apache2 reload
我尝试添加以下行没有运气
ip=$(head -n 1 $ip)
如果有人能告诉我如何从变量$ ip中提取IP地址的第一个实例,我会非常感激。
答案 0 :(得分:6)
ip=$(last -i | head -n 1 | awk '{print $3}')
<强>更新强>
ip=$(last -i | grep -Pom 1 '[0-9.]{7,15}')
答案 1 :(得分:6)
您可以将grep
与read
:
read ip < <(last -i | grep -o '[0-9]\+[.][0-9]\+[.][0-9]\+[.][0-9]\+')
read ip < <(last -i | grep -Eo '[0-9]+[.][0-9]+[.][0-9]+[.][0-9]+')
\b
也可能对您有所帮助。只是不确定它的兼容性。而另一个:
ip=$(last -i | gawk 'BEGIN { RS = "[ \t\n]"; FS = "." } /^([0-9]+[.]){3}[0-9]+$/ && ! rshift(or(or($1, $2), or($3, $4)), 8) { print ; exit; }')
答案 2 :(得分:3)
我只是做
ip=$(last -i -1 | grep -Po '(\d+\.){3}\d+')
以上使用grep
和Perl兼容正则表达式,我们可以使用\d
来表示数字。正则表达式查找三个重复的[0-9]
后跟一个点(例如123.45.123
),然后是另一段数字。 -o
标记导致grep
仅打印匹配的行。
这种方法的优点是即使每行的字段数发生变化也是如此(通常情况下,例如将system boot
作为第二个字段)。但是,它需要GNU grep,因此如果您需要更便携的解决方案,请改用@konsolebox's answer。
答案 3 :(得分:2)
要获得第一个实例,您可以这样做:
ip=$(last -i -1 | awk '{print $3}')
答案 4 :(得分:0)
仅使用bash:
read -ra array < <(last -i)
ip="${array[2]}"
或者:
read -ra array < <(last -1 -i)
ip="${array[2]}"
答案 5 :(得分:0)
或者如果你是一个挑剔的人(并且有-P
的grep),你可以测试下一个:
while read -r testline
do
echo "input :=$testline="
read ip < <(grep -oP '\b(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))\b' <<< "$testline")
echo "result:=${ip:=NOTFOUND}="
echo
done <<EOF
some bla bla 127.0.0.1 some
10.10.10.10
bad one 300.200.300.400
some other bla 127.0.0.1 some another 10.1.1.0
10.10.10.10 10.1.1.0
bad one 300.200.300.400 and good 192.168.1.1
above is empty and no ip here too
EOF
它跳过错误的ip adr,如800.1.1.1
所以,对于上面的测试打印:
input :=some bla bla 127.0.0.1 some=
result:=127.0.0.1=
input :=10.10.10.10=
result:=10.10.10.10=
input :=bad one 300.200.300.400=
result:=NOTFOUND=
input :=some other bla 127.0.0.1 some another 10.1.1.0=
result:=127.0.0.1=
input :=10.10.10.10 10.1.1.0=
result:=10.10.10.10=
input :=bad one 300.200.300.400 and good 192.168.1.1=
result:=192.168.1.1=
input :==
result:=NOTFOUND=
input :=above is empty and no ip here too=
result:=NOTFOUND=
需要\b
来跳过匹配的ip,例如:610.10.10.10,包含有效ip的内容(10.10.10.10)。
答案 6 :(得分:0)
由于我碰巧需要在同一个球场做某事,这里有一个基本的正则表达式和一个扩展的正则表达式,以便与IP地址(v4)松散匹配,确保有4个1-3个数字的序列分隔一个3'。'。
# Basic Regular Expression to loosly match an IP address:
bre_match_ip="[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"
# Extended Regular Expression to loosly match an IP address:
ere_match_ip="[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"
当然,当从文件(比如HTML)匹配IP(v4)地址时,很容易无意中匹配版本字符串或包含版本控制作为其文件路径一部分的URL。以下是我刚才写的一些Awk代码,用于在Bash脚本中从文件中提取有效的唯一(无重复)IP地址。它避免使用版本号,无论是在文本中还是作为URL的一部分,并确保IP号在范围内。
我很欣赏这对于原始海报来说太过分了,并且它不是为他的需求量身定制的,但是进行搜索的人可能会遇到这个答案,并发现代码的相当全面的性质很有用。值得一提的是Awk代码评论很好,因为它使用了awk的一些略显模糊的方面,而Awk用户可能并不熟悉。
awkExtractIPAddresses='
BEGIN {
# Regex to match an IP address like sequence (even if too long to be an IP).
# This is deliberately a loose match, the END section will check for IP
# address validity.
ipLikeSequence = "[0-9]+[.][0-9]+[.][0-9]+[.][0-9]+[0-9.]*";
# Regex to match a number sequence longer than 3 digits.
digitSequenceTooLongNotIP = "[0-9][0-9][0-9][0-9]+";
# Regex to match an IP address like sequence which is a version number.
# Equivalent to "(version|ver|v)[ .:]*" if "tolower($0)" was used.
versioningNotIP = "[Vv]([Ee][Rr]([Ss][Ii][Oo][Nn])?)?[ .:]*" ipLikeSequence;
# Regexes to match IP address like sequences next to forward slashes, to
# avoid version numbers in urls: e.g. http://web.com/libs/1.6.1.0/file.js
beginsWithFwdSlashNotIP = "[/]" ipLikeSequence;
endsWithFwdSlashNotIP = ipLikeSequence "[/]";
}
{
# Set line to the current line (more efficient than using $0 below).
line = $0;
# Replace sequences on line which will interfere with extracting genuine
# IPs. Use a replacement char and not the empty string to avoid accidentally
# creating a valid IP address from digits on either side of the removed
# sections. Use "/" as the replacement char for the 2 "FwdSlash" regexes so
# that multiple number dot slash sequences all get removed, as using "x"
# could result in inadvertently leaving such a sequence in place.
# e.g. "/lib1.6.1.0/1.2.3.4/5.6.7.8/file.js" leaves "/lib1.6.1.0xx/file.js"
gsub(digitSequenceTooLongNotIP, "x", line);
gsub(versioningNotIP, "x", line);
gsub(beginsWithFwdSlashNotIP, "/", line);
gsub(endsWithFwdSlashNotIP, "/", line);
# Loop through the current line matching IP address like sequences and
# storing them in the index of the array ipUniqueMatches. By using ipMatch
# as the array index duplicates are avoided and the values can be easily
# retrieved by the for loop in the END section. match() automatically sets
# the built in variables RSTART and RLENGTH.
while (match(line, ipLikeSequence))
{
ipMatch = substr(line, RSTART, RLENGTH);
ipUniqueMatches[ipMatch];
line = substr(line, RSTART + RLENGTH + 1);
}
}
END {
# Define some IP address related constants.
ipRangeMin = 0;
ipRangeMax = 255;
ipNumSegments = 4;
ipDelimiter = ".";
# Loop through the ipUniqueMatches array and print any valid IP addresses.
# The awk "for each" type of loop is different from the norm. It provides
# the indexes of the array and NOT the values of the array elements which
# is more usual in this type of loop.
for (ipMatch in ipUniqueMatches)
{
numSegments = split(ipMatch, ipSegments, ipDelimiter);
if (numSegments == ipNumSegments &&
ipSegments[1] >= ipRangeMin && ipSegments[1] <= ipRangeMax &&
ipSegments[2] >= ipRangeMin && ipSegments[2] <= ipRangeMax &&
ipSegments[3] >= ipRangeMin && ipSegments[3] <= ipRangeMax &&
ipSegments[4] >= ipRangeMin && ipSegments[4] <= ipRangeMax)
{
print ipMatch;
}
}
}'
# Extract valid IP addresses from $fileName, they will each be separated
# by a new line.
awkValidIpAddresses=$(awk "$awkExtractIPAddresses" < "$fileName")
我希望这很有意思。
答案 7 :(得分:0)
你可以使用Awk。
ip=$(awk '{if(NR == 1) {print $3; exit;}}' < <(last -i))