Permalänk
Medlem

Bash script för statisk IP

Håller på att trixa lite med ett bash-script som ska köras som ett startup-script på en VM med DHCP. Tanken är att scriptet ska låsa DHCP adressen så att den blir statisk.

Finns det något bättre sätt att göra det på än såhär:

# Change to static IP IP="$(ifconfig eth0 | awk -F"[: ]+" '/inet addr:/ {print $4}')" GATEWAY="$(/sbin/ip route | awk '/default/ { print $3 }')" BCAST="$(ip addr show |grep -w inet |grep -v 127.0.0.1|awk '{ print $4}')" NETMASK="$(ifconfig | grep -w inet |grep -v 127.0.0.1| awk '{print $4}' | cut -d ":" -f 2)" IPWRITE="$(echo adress $IP)" GATEWAYWRITE="$(echo gateway $GATEWAY)" BCASTWRITE="$(echo broadcast $BCAST)" NETMASKWRITE="$(echo netmask $NETMASK)" AUTOLO="$(echo -e "auto lo\niface lo inet loopback")" ETH0="$(echo -e "auto eth0\niface eth0 inet static")" printf "$AUTOLO\n$ETH0\n$IPWRITE\n$GATEWAYWRITE\n$BCASTWRITE\n$NETMASKWRITE" > /etc/network/interfaces exit 0

Och sen undrar jag om jag kan få fram "network" på något sätt? Alltså 192.168.1.0.

Visa signatur

Citera för svar

- Stora Owncloud/Nextcloud-tråden: http://www.sweclockers.com/forum/122-server/1212245-officiell...
- Jobbar på: T&M Hansson IT AB https://www.hanssonit.se

Permalänk
Medlem

Är det på klienten du försöker låsa det till ett statiskt IP?
I så fall är det väl bättre att göra den inställningen på DHCP-servern?
Har du en riktigt server för DHCP eller är det en router? de flesta router kan låsa DHCP IP till en speciell maskin.

Permalänk
Hedersmedlem
Skrivet av enoch85:

Håller på att trixa lite med ett bash-script som ska köras som ett startup-script på en VM med DHCP. Tanken är att scriptet ska låsa DHCP adressen så att den blir statisk.

Rätt plats att lösa det på låter spontant som ovanstående säger vara serversidan, där man brukar kunna låsa anslutande klienter till specifika IP-nummer beroende på MAC-adress.

Lite skriptnotiser i vilket fall:

Skrivet av enoch85:

# Change to static IP IP="$(ifconfig eth0 | awk -F"[: ]+" '/inet addr:/ {print $4}')" GATEWAY="$(/sbin/ip route | awk '/default/ { print $3 }')" BCAST="$(ip addr show |grep -w inet |grep -v 127.0.0.1|awk '{ print $4}')" NETMASK="$(ifconfig | grep -w inet |grep -v 127.0.0.1| awk '{print $4}' | cut -d ":" -f 2)"

Du behöver inte ha citationstecken när du tilldelar en variabel ett värde direkt från ett `$`-uttryck, så alla de kan skippas. Det blir inget problem med mellanrum ändå — skalet förstår att högerledet är en variabel automatiskt här. Det är definierat i POSIX.

Första radens AWK-användande ser rätt rent ut. Är man bara intresserad av ett värde så kan man lägga till `; exit` i kroppen så att skriptet avslutas efter att ha träffat en gång, i stället för att fortsätta söka genom resten av ingående rader. Inte prestandakritiskt här precis, men bra att känna till.

Vad gäller `BCAST` och `NETMASK` så behöver du inte blanda in `grep` om du ändå öser på med hela `awk`, då det senare gott och väl kan lösa det som `grep` gör här. `BCAST="$(ip addr show |grep -w inet |grep -v 127.0.0.1|awk '{ print $4}')"` kan `awk` göra helt själv genom:

BCAST=$(ip addr show | awk '/\<inet\>/ && !/127\.0\.0\.1/ {print $4; exit}')

där `\<inet\>` bara träffar fristående `inet` och `!//` plockar bort det som träffar mönstret.

På samma sätt kan `NETMASK` förenklas, där du också med fördel kan använda samma fältavgränsardefinition som användes för `IP` samt definiera gränssnittet för `ifconfig`:

NETMASK=$(ifconfig eth0 | awk -F'[: ]+' '/\<inet\>/ {print $8; exit}')

Det är ofta positivt att undvika långa pipeharanger som kräver en process var, speciellt när man i detta fall ändå drar igång AWK och har all dess kraft tillgänglig.

Skrivet av enoch85:

IPWRITE="$(echo adress $IP)" GATEWAYWRITE="$(echo gateway $GATEWAY)" BCASTWRITE="$(echo broadcast $BCAST)" NETMASKWRITE="$(echo netmask $NETMASK)" AUTOLO="$(echo -e "auto lo\niface lo inet loopback")" ETH0="$(echo -e "auto eth0\niface eth0 inet static")" printf "$AUTOLO\n$ETH0\n$IPWRITE\n$GATEWAYWRITE\n$BCASTWRITE\n$NETMASKWRITE" > /etc/network/interfaces exit 0

Använd heredoc-syntax i stället och dirigera resultatet direkt till filen:

cat <<-IPCONFIG > /etc/network/interfaces auto lo iface lo inet loopback auto eth0 iface eth0 inet static address $IP gateway $GATEWAY broadcast $BCAST netmask $NETMASK IPCONFIG

där jag också fixade felstavningen "adress" → "address" (bara ett "d" i svenska, men två i engelska).

Det är också ofta trevligt att definiera exempelvis sökvägar som `/etc/network/interfaces` som konstanter högst upp i filen för att separera sådana detaljer från själva implementationen, och minimera risk för "slarvfel". Det kanske inte verkar speciellt nödvändigt i ett så här litet skript, men det är en god vana.

Skrivet av enoch85:

Och sen undrar jag om jag kan få fram "network" på något sätt? Alltså 192.168.1.0.

Det behövs inte för att konfigurera gränssnittet, då informationen kan läsas ut från IP-adressen och nätmasken (detta gäller även broadcast).

Sammanlagt, med några ytterligare minimala modifikationer, ger detta något i stil med:

#!/bin/sh IFACE="eth0" IFCONFIG="/sbin/ifconfig" IP="/sbin/ip" INTERFACES="/etc/network/interfaces" ADDRESS=$($IFCONFIG $IFACE | awk -F'[: ]+' '/\<inet\>/ {print $4; exit}') NETMASK=$($IFCONFIG $IFACE | awk -F'[: ]+' '/\<inet\>/ {print $8; exit}') GATEWAY=$($IP route | awk '/\<default\>/ {print $3; exit}') cat <<-IPCONFIG > "$INTERFACES" auto lo $IFACE iface lo inet loopback iface $IFACE inet static address $ADDRESS netmask $NETMASK gateway $GATEWAY IPCONFIG

Komplett otestat, och som sagt: detta bör lösas på serversidan i stället, så detta skript borde inte ens existera . Denna variant ser i mina ögon mer läsbar och konsekvent ut, dock. Man skulle kunna roa sig med att plocka all önskad information ut `ifconfig` på en enda körning, men det blir lätt mindre uppenbart vad som händer, vilket som regel är negativt.

Kan också nämna att det inte är speciellt portabelt att tyda output från `ifconfig` på detta sätt, men kör du bara på en typ av system (exempelvis Debianbaserade) så spelar det mindre roll.

Visa signatur

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Permalänk
Medlem
Skrivet av phz:

Rätt plats att lösa det på låter spontant som ovanstående säger vara serversidan, där man brukar kunna låsa anslutande klienter till specifika IP-nummer beroende på MAC-adress.

Lite skriptnotiser i vilket fall:

Du behöver inte ha citationstecken när du tilldelar en variabel ett värde direkt från ett `$`-uttryck, så alla de kan skippas. Det blir inget problem med mellanrum ändå — skalet förstår att högerledet är en variabel automatiskt här. Det är definierat i POSIX.

Första radens AWK-användande ser rätt rent ut. Är man bara intresserad av ett värde så kan man lägga till `; exit` i kroppen så att skriptet avslutas efter att ha träffat en gång, i stället för att fortsätta söka genom resten av ingående rader. Inte prestandakritiskt här precis, men bra att känna till.

Vad gäller `BCAST` och `NETMASK` så behöver du inte blanda in `grep` om du ändå öser på med hela `awk`, då det senare gott och väl kan lösa det som `grep` gör här. `BCAST="$(ip addr show |grep -w inet |grep -v 127.0.0.1|awk '{ print $4}')"` kan `awk` göra helt själv genom:

BCAST=$(ip addr show | awk '/\<inet\>/ && !/127\.0\.0\.1/ {print $4; exit}')

där `\<inet\>` bara träffar fristående `inet` och `!//` plockar bort det som träffar mönstret.

På samma sätt kan `NETMASK` förenklas, där du också med fördel kan använda samma fältavgränsardefinition som användes för `IP` samt definiera gränssnittet för `ifconfig`:

NETMASK=$(ifconfig eth0 | awk -F'[: ]+' '/\<inet\>/ {print $8; exit}')

Det är ofta positivt att undvika långa pipeharanger som kräver en process var, speciellt när man i detta fall ändå drar igång AWK och har all dess kraft tillgänglig.

Använd heredoc-syntax i stället och dirigera resultatet direkt till filen:

cat <<-IPCONFIG > /etc/network/interfaces auto lo iface lo inet loopback auto eth0 iface eth0 inet static address $IP gateway $GATEWAY broadcast $BCAST netmask $NETMASK IPCONFIG

där jag också fixade felstavningen "adress" → "address" (bara ett "d" i svenska, men två i engelska).

Det är också ofta trevligt att definiera exempelvis sökvägar som `/etc/network/interfaces` som konstanter högst upp i filen för att separera sådana detaljer från själva implementationen, och minimera risk för "slarvfel". Det kanske inte verkar speciellt nödvändigt i ett så här litet skript, men det är en god vana.

Det behövs inte för att konfigurera gränssnittet, då informationen kan läsas ut från IP-adressen och nätmasken (detta gäller även broadcast).

Sammanlagt, med några ytterligare minimala modifikationer, ger detta något i stil med:

#!/bin/sh IFACE="eth0" IFCONFIG="/sbin/ifconfig" IP="/sbin/ip" INTERFACES="/etc/network/interfaces" ADDRESS=$($IFCONFIG $IFACE | awk -F'[: ]+' '/\<inet\>/ {print $4; exit}') NETMASK=$($IFCONFIG $IFACE | awk -F'[: ]+' '/\<inet\>/ {print $8; exit}') GATEWAY=$($IP route | awk '/\<default\>/ {print $3; exit}') cat <<-IPCONFIG > "$INTERFACES" auto lo $IFACE iface lo inet loopback iface $IFACE inet static address $ADDRESS netmask $NETMASK gateway $GATEWAY IPCONFIG

Komplett otestat, och som sagt: detta bör lösas på serversidan i stället, så detta skript borde inte ens existera . Denna variant ser i mina ögon mer läsbar och konsekvent ut, dock. Man skulle kunna roa sig med att plocka all önskad information ut `ifconfig` på en enda körning, men det blir lätt mindre uppenbart vad som händer, vilket som regel är negativt.

Kan också nämna att det inte är speciellt portabelt att tyda output från `ifconfig` på detta sätt, men kör du bara på en typ av system (exempelvis Debianbaserade) så spelar det mindre roll.

Dold text

Mycket bra svar! Tack! Ska prova när jag kommer hem.

EDIT: Detta blev det slutgiltiga. Jag saxade BCAST från det du skrev. Funkar utmärkt!

#!/bin/sh IFACE="eth0" IFCONFIG="/sbin/ifconfig" IP="/sbin/ip" INTERFACES="/etc/network/interfaces" ADDRESS=$($IFCONFIG $IFACE | awk -F'[: ]+' '/\<inet\>/ {print $4; exit}') NETMASK=$($IFCONFIG $IFACE | awk -F'[: ]+' '/\<inet\>/ {print $8; exit}') GATEWAY=$($IP route | awk '/\<default\>/ {print $3; exit}') BCAST=$(ip addr show | awk '/\<inet\>/ && !/127\.0\.0\.1/ {print $4; exit}') cat <<-IPCONFIG > "$INTERFACES" auto lo $IFACE iface lo inet loopback iface $IFACE inet static address $ADDRESS netmask $NETMASK gateway $GATEWAY broadcast $BCAST IPCONFIG exit 0

Visa signatur

Citera för svar

- Stora Owncloud/Nextcloud-tråden: http://www.sweclockers.com/forum/122-server/1212245-officiell...
- Jobbar på: T&M Hansson IT AB https://www.hanssonit.se

Permalänk
Hedersmedlem
Skrivet av enoch85:

EDIT: Detta blev det slutgiltiga. Jag saxade BCAST från det du skrev. Funkar utmärkt!

Som jag skrev så behöver du varken broadcast- eller nätverksadress då systemet själv kan räkna ut dessa adresser genom IP och nätmask. Det enda som kan hända av att ange dessa adresser är att de råkar bli fel, varpå nätverket inte kommer fungera.

Visa signatur

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Permalänk
Medlem
Skrivet av phz:

Som jag skrev så behöver du varken broadcast- eller nätverksadress då systemet själv kan räkna ut dessa adresser genom IP och nätmask. Det enda som kan hända av att ange dessa adresser är att de råkar bli fel, varpå nätverket inte kommer fungera.

Tack! Har alltid trott att det var tvärtom. Heureka.

Visa signatur

Citera för svar

- Stora Owncloud/Nextcloud-tråden: http://www.sweclockers.com/forum/122-server/1212245-officiell...
- Jobbar på: T&M Hansson IT AB https://www.hanssonit.se