Bash: попытка получить общедоступный IPv6 с помощью функции

Я пытаюсь проверить, есть ли что-нибудь в моем общедоступном IPv6, если нет, то выведите текст «Неизвестно» в переменную (для хранения). Затем отобразите переменную позже в тексте, например: echo "Public IPv6: "$PIP6 (переменная, которую нужно сохранить).

Я знаю, что у меня нет общедоступного IPv6 (в моей стране он появляется медленно), поэтому я ожидаю, что там будет написано «Неизвестно». Но там пусто.

В чем проблема?

test.sh

#!/bin/bash
OS = "$(uname)"
InternalIP = ""
LIP = "ip addr show"
LIP6 = "ip -6 addr show scope global"
IPv6 = ""
PIPv6 = ""

case $OS in
 *)InternalIP=$($LIP | grep 'inet'| grep -v '127.0.0.1' | cut -d: -f2 | awk 'NF>0{print $2}');;
esac
case $OS in
 *)IPv6=$($LIP | grep 'inet6' | grep -v '128' | awk '{print $2}');;
esac
case $OS in
 *)PIPv6=$($LIP6 | grep 'inet6' | grep -v '128' | awk '{print $2}');;
esac
   if [ -z $PIPv6 ]; then
    echo $PIPv6
   else
    echo "Unknown"
   fi

length=$InternalIP
echo $InternalIP | awk '{print substr($0, 1, length($0)-3)}'
echo $IPv6 | awk '{print substr($0, 1, length($0)-3)}'
echo "Public IPv6: "$PIPv6

Я пробовал разные стили if. попробовал использовать echo "Unknown вместо результата, а затем он появился как Неизвестно, но я хочу, чтобы он был сохранен в переменной, а не отображался в начале вывода:

Unknown
1xx.xxx.xxx.xxx
xxxx::xxxx:xxxx:xxxx:xxx
Public IPv6: 

Теперь, когда я запускаю файл: publicip.sh

#!/bin/bash
LIB = "ip address show" # Show Network Information
PIB6 = "ip -6 adress show scope global" # Public IPv6

IPv4 = "$($LIB | awk '/inet/ && !/127/ && !/128/ && !/64/{print $2}')"
IPv6 = "$($LIB | awk '/inet6/ && !/128/{print $2}')"
PIPv4 = "$(dig +short myip.opendns.com @resolver1.opendns.com)"
PIPv6 = "$($PIP6 | awk '/inet6/ && !/128/{print $2}')"

if [ -z "$PIPv6" ]; then
  PIPv6 = "unknown"
fi

echo "Local IPv4: $IPv4" | awk '{print substr($0,1,length($0)-3)}'
echo "Local IPv6: $IPv6" | awk '{print substr($0,1,length($0)-3)}'
echo "Public IPv4: $PIPv4"
echo "Public IPv6: $PIPv6"

Выход:

Local IPv4: xxx.xxx.xxx.xxx
Local IPv6: xxxx::xxxx:xxxx:xxxx:xxx
Public IPv4: xxx.xxx.xxx.xxx
Public IPv6: Unknown

Так же, как я этого хочу.

ваш тест кажется (а) обратным: if [ -z $PIPv6 ]; then echo $PIPv6 кажется, хочет напечатать значение, когда оно пусто, а не когда оно не пусто, и (б) глючит - когда $PIPv6 пусто, потому что вы не указали переменную, тест становится if [ -z ]; then echo $PIPv6, что все равно удается (поскольку строка «-z» не пуста)

jhnc 23.03.2024 17:44

Если я правильно понимаю, чего вы хотите, вы хотите, чтобы переменная PIPv6 имела значение Unknown, если вы не нашли адрес IPv6. Код не работает, поскольку он не пытается изменить значение переменной, если обнаруживает, что ее значение пусто. Простое решение проблемы — заменить echo "Unknown" на PIPv6=Unknown. Другой вариант — использовать один из методов, описанных в ответах на предложенный мной повторяющийся вопрос. Один из способов сделать это — заменить if [ -z $PIPv6 ] ... fi на : "${PIPv6:=Unknown}".

pjh 23.03.2024 18:17

pjh: Вроде то же самое, но я не могу понять ни этот код, ни то, как он формируется. Но спасибо. И спасибо за ссылку на проверку орфографии. Не знал об этом. Я совершенно новичок в программировании на Bash.

Cordux 23.03.2024 22:43
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
4
128
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Попробуйте это, непроверенное:

#!/usr/bin/env bash

InternalIP = ""
lip() { ip addr show; }
lip6() { ip -6 addr show scope global; }
IPv6 = ""
PIPv6 = ""

InternalIP=$(lip | awk -F':' '/inet/ && !/127\.0\.0\.1/ && split($2,a," ")>1{print a[2]}')
IPv6=$(lip | awk '/inet6/ && !/128/{print $2}')
PIPv6=$(lip6 | awk '/inet6/ && !/128/{print $2}')

if [[ -z $PIPv6 ]]; then
    PIPv6='Unknown'
fi

echo "$InternalIP" | awk '{print substr($0, 1, length($0)-3)}'
echo "$IPv6" | awk '{print substr($0, 1, length($0)-3)}'
echo "Public IPv6: $PIPv6"

Я не понимаю часть вашего кода, и вы не предоставили вывод своих двух ip команд, поэтому я не знаю, почему вы используете команды, которые вы используете, поэтому приведенное выше — это просто перевод вашего кода на Я думаю, что ты хотел, чтобы это сделало.

Самым значительным изменением, вероятно, является то, что, как мне кажется, вы хотели установить для PIPv6 значение Unknown, когда он пуст, а не просто печатать пустую строку.

Я попробовал то, что вы написали. awk для InternalIP не будет работать, когда я попробую его в терминале (lLinux), он окажется пустым.

Cordux 23.03.2024 22:47

@Cordux Как я уже говорил, я просто догадываюсь, что вам нужно, поскольку вы не показали нам вывод своих ip команд. Что бы ни было неправильно в awk-скрипте, исправить это будет несложно, если вы отредактируете свой вопрос, чтобы отобразить эту информацию.

Ed Morton 23.03.2024 22:49

Если вы посмотрите на вопрос еще раз, вы увидите весь файл. Я заставил его работать.

Cordux 23.03.2024 22:50

Вы показываете весь свой скрипт, но не единственное, что нам действительно нужно вам помочь, а именно выходные данные двух команд, которые вы пытаетесь проанализировать — ip addr show и ip -6 addr show scope global. «заработало» — относительно. Вы делаете несколько вещей, которые не имеют смысла, например. эти операторы случая, некоторые из которых содержат ошибки, например. не экранировать . в вашем регулярном выражении, а также некоторые хорошо известные антишаблоны, например. сохраняя код в переменных, это может стать для вас хорошей возможностью узнать немного больше о программировании на bash.

Ed Morton 23.03.2024 22:52

ip addr show — это команда для отображения сетевой информации практически в любой версии Linux (я думаю). Итак, каждый берет эту информацию, а затем выполняет grep то, что мне нужно (слово inet в первом месте, затем переворачивает (-v) и удаляет это с помощью localhost-ip(127.0.0.01)). Cut удаляет первую и третью строку ( по крайней мере, то, что я знаю), затем NF>0 после этого забирает пустые строки, а затем записывает только с помощью awk. (Это мое понимание.)

Cordux 23.03.2024 22:59

В настоящее время у меня нет Linux, и у меня нет команды ip, но это не имеет значения — если вы отредактируете свой вопрос, чтобы показать выходные данные, которые ВЫ получаете от этих команд, мы сможем вам помочь. Я знаю, что делают команды, которые вы используете, и показал то, что я считаю awk-эквивалентом каждого командного конвейера, но если он не выдает ожидаемый результат, возможно, я ошибся, но я не узнаю, пока Я вижу текст, который вы пытаетесь разобрать. Увидев результат, я, вероятно, смогу предложить более надежный способ его анализа, поскольку сопоставление регулярного выражения по всей каждой строке является хрупким.

Ed Morton 23.03.2024 23:01

И мы определенно сможем избавиться от двух дополнительных вызовов awk в конце вашего сценария, как только узнаем, как выглядят входные данные. (Я говорю «мы», поскольку многие люди, публикующие здесь сообщения, могут помочь вам, если вы предоставите недостающую информацию, а не только я).

Ed Morton 23.03.2024 23:09

Непроверено, но должно работать: когда вы проверяете, пуст ли PIPv6, и пытаетесь вывести «Неизвестно», если он не установлен, логика вашего скрипта инвертируется. Вы повторяете $PIPv6, когда он пуст (который просто ничего не печатает, поскольку PIPv6 пуст) и печатаете «Неизвестно», когда он не пуст, что является противоположностью того, к чему вы стремитесь.

Кроме того, вы хотите сохранить значение «Неизвестно» в переменной PIPv6, если IPv6 не найден, а не просто отображать его. Вот исправленная версия вашего скрипта с исправленной логикой и назначением переменных:

#!/bin/bash
OS = "$(uname)"
InternalIP = ""
LIP = "ip addr show"
LIP6 = "ip -6 addr show scope global"
IPv6 = ""
PIPv6 = ""

case $OS in
 *)InternalIP=$($LIP | grep 'inet'| grep -v '127.0.0.1' | cut -d: -f2 | awk 'NF>0{print $2}');;
esac
case $OS in
 *)IPv6=$($LIP | grep 'inet6' | grep -v '128' | awk '{print $2}');;
esac
case $OS in
 *)PIPv6=$($LIP6 | grep 'inet6' | grep -v '128' | awk '{print $2}');;
esac

# Check if PIPv6 is empty and set to "Unknown" if it is
if [ -z "$PIPv6" ]; then
    PIPv6 = "Unknown"
fi

length=$InternalIP
echo $InternalIP | awk '{print substr($0, 1, length($0)-3)}'
echo $IPv6 | awk '{print substr($0, 1, length($0)-3)}'
echo "Public IPv6: "$PIPv6

Теперь скрипт будет правильно выводить «Неизвестно» для общедоступного IPv6-адреса, если он не найден, и сохранит его в переменной PIPv6 для дальнейшего использования, как вы и предполагали. Пожалуйста, внесите другие изменения соответствующим образом.

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

Ed Morton 23.03.2024 22:51

Другие вопросы по теме