Shell 将变量输入到awk脚本
我正在编写一个脚本,用于检测网卡上的CDP信息。该脚本目前在我的计算机上运行,但我希望其他人也能使用它。脚本当前正在运行,因为在代码中它有我的网卡的名称。在运行脚本之前,我想让它询问网卡名称,或者列出可用的网卡名称。我的代码是:Shell 将变量输入到awk脚本,shell,awk,Shell,Awk,我正在编写一个脚本,用于检测网卡上的CDP信息。该脚本目前在我的计算机上运行,但我希望其他人也能使用它。脚本当前正在运行,因为在代码中它有我的网卡的名称。在运行脚本之前,我想让它询问网卡名称,或者列出可用的网卡名称。我的代码是: #!/usr/bin/awk -f function red(s) { printf "\033[1;31m" s "\033[0m " } function green(s) { printf "\033[1;32m" s "\033[0m "
#!/usr/bin/awk -f
function red(s) {
printf "\033[1;31m" s "\033[0m "
}
function green(s) {
printf "\033[1;32m" s "\033[0m "
}
function blue(s) {
printf "\033[1;34m" s "\033[0m "
}
BEGIN{
cmd = "tcpdump -nvi enp0s25 -s 1500 ether dst 01:00:0c:cc:cc:cc -c 1"
while ((cmd | getline) > 0) {
str="Device-ID:Cisco IOS Software:Port-ID:VTP:Address:VLAN:Duplex:VoIP:"
split(str,s,":")
for(i=1;i<=length(s);i++){
if ($0 ~ s[i] && s[i]){
if (i==1){
print "\n";
print red("Device Name: ") green($7);
}
else if (i==2){
print red("Software Version: ") green($0) ;
}
else if (i==3){ /*Port*/
print red($1 ": ") green($7);
}
else if (i==4){
print red($1 " " $2 " " $3 ": ") green($9);
}
else if (i==5){
print red("IP Address: ") green($9);
}
else if (i==6){
print red("VLAN: ") green($9);
}
else if (i==7){
print red("DUPLEX: ") green($7);
}
else if (i==8){
print red("Voice VLAN: ") green($13);
}
else{
s[i]=0;print " "}
}
}
}
}
如您所见,它使用我的NIC enp0s25运行命令。我需要把它变成一个变量,用户可能只输入一次。最好的方法是列举卡片,让用户使用数字选择他想要的卡片。我不知道如何做到这一点。您试图将awk作为shell使用,将对tcpdump的调用编码到awk中,这让您的生活更加艰难。考虑一下——您正在编写一个shell脚本来调用awk来调用shell来调用tcpdump,而不是让shell调用tcpdump并将输出通过管道传输到awk
#!/usr/bin/awk -f
function red(s) {
printf "\033[1;31m" s "\033[0m "
}
function green(s) {
printf "\033[1;32m" s "\033[0m "
}
function blue(s) {
printf "\033[1;34m" s "\033[0m "
}
function detectNic( ) {
printf "Enter the Ethernet card to listen or press enter to listen
to Default:";getline nic<"/dev/tty"
if (nic == ""){
command = "cat /var/defaultnic"
nic = command | getline
print "Default network card to listen: " $nic
return $nic
}
else{
return nic
}
}
BEGIN{
nic = detectNic();
cmd = "tcpdump -nv -s 1500 ether dst 01:00:0c:cc:cc:cc -c 1 -i"
while ((cmd nic | getline) > 0) {
str="Device-ID:Cisco IOS Software:Port-ID:VTP:Address:VLAN:Duplex:VoIP:"
split(str,s,":")
for(i=1;i<=length(s);i++){
if ($0 ~ s[i] && s[i]){
#DEVICE ID
if (i==1){
print "\n";
print red("Device Name: ") green($7);
}
#SOFTWARE VERSION
else if (i==2){
print red("Software Version: ") green($0) ;
}
#PORT
else if (i==3){
print red($1 ": ") green($7);
}
#VTP DOMAIN
else if (i==4){
print red($1 " " $2 " " $3 ": ") green($9);
}
#IP ADDRESS
else if (i==5){
print red("IP Address: ") green($9);
}
#CURRENT VLAN
else if (i==6){
print red("VLAN: ") green($9);
}
#DUPLEX
else if (i==7){
print red("DUPLEX: ") green($7);
}
#VOICE VLAN
else if (i==8){
print red("Voice VLAN: ") green($13);
}
else{
s[i]=0;print " "}
}
}
}
}
只需将shell脚本编写为:
tcpdump ... enp0s25 ... | awk 'script'
然后你可以用显而易见的方式来调整它:
echo "enter a nic: "
IFS= read -r nic
tcpdump ... "$nic" ... | awk 'script'
为什么要绕过awks的正常操作模式,例如tcpdump args | awk“script”,而硬编码getline循环?稍后我将回到您的实际问题,但您使用的printf是错误的:如果字符串包含%序列,您将得到一个错误。您需要将参数保留在格式字符串之外。我将执行函数着色,n{printf\033[1;%dm%s\033[0m,n,s},然后执行函数reds{colorizes,31},etcnic=command | getline;return$nic将nic设置为结果状态,即不是getline调用检测到的值-1、0或1,然后返回位于该位置的字段或记录$-1、0或$1。可能不是您试图执行的操作。并将文件传送到管道到getline,而不是像以前那样使用getline读取文件几行之前的getline nic