0

ユーザー入力をキャプチャし、ネットワーク構成プロセスを自動化する、メニュー駆動のモジュラー perl スクリプトを作成しようとしています。このスクリプトは、必要な Arch パッケージをインストールし、AP モードを構成し、ユーザーが選択したインターフェイスの DHCP または静的アドレスを構成し、ブリッジを有効にするオプションを提供できる必要があります。(編集: スクリプトは、dhcpd サービスを有効にして構成できる必要もあります)

私が今立ち往生している部分は、rc.conf ファイルのバックアップを作成し、ファイルを読み取り、ネットワーク インターフェイスが既に静的に構成されている場合に変更する必要がある行を編集することです。このスクリプトは ArchLinux で使用するためのものです。いくつか検索しましたが、特に私のニーズを満たすものは見つかりませんでした。

汎用入力の使用 $ip = 1.1.1.1; $Bcast = 2.2.2.2; $netmask = 3.3.3.3; $GW = 4.4.4.4;

私はファイル I/O について読むのに約 2 時間を費やしましたが、複数ファイル IO メソッドを破棄し、次のようなものを使用するなど、うまくいかないことをいくつか試しましたwhile(<IS>){s/^interface.?=(.*)$/"interface=@if[0] \n"/;}。実際に何かをすることはできません。

   if (system ("cat","/etc/rc.conf","|","grep","interface")){   
    use File::Copy "cp";
    $filename = "/etc/rc.conf"; 
    $tempfile = "/etc/rc.tmp";  
    $bak = "/etc/rc.bak";
    cp($filename,$bak);
    open(IS, $filename); 
    open(OS, ">$tempfile"); 
    while(<IS>){ 
        if($_ =~ /^interface.?=(.*)$/){ print OS"interface=@if[0] \n";}
        if($_ =~ /^address.?=(.*)$/){ print OS "address=$ip\n";}
        if($_ =~/^netmask.?=(.*)$/){ print OS "netmask=$netmask\n";}
        if($_ =~/^broadcast.?=(.*)$/){ print OS "broadcast=$Bcast\n";}
        if($_ =~/^gateway.?=(.*)$/){ print OS "gateway=$GW\n"; }
        else {print OS $_;} 
    }
    close(IS); close(OS); 
    unlink($filename); rename($tempfile, $filename);
}

前のrc.conf

#
# /etc/rc.conf - Main Configuration for Arch Linux

. /etc/archiso/functions

LOCALE_DEFAULT="en_US.UTF-8"
DAEMON_LOCALE_DEFAULT="no"
CLOCK_DEFAULT="UTC"
TIMEZONE_DEFAULT="Canada/Pacific"
KEYMAP_DEFAULT="us"
CONSOLEFONT_DEFAULT=
CONSOLEMAP_DEFAULT=
USECOLOR_DEFAULT="yes"

LOCALE="$(kernel_cmdline locale ${LOCALE_DEFAULT})"
DAEMON_LOCALE="$(kernel_cmdline daemon_locale ${DAEMON_LOCALE_DEFAULT})"
HARDWARECLOCK="$(kernel_cmdline clock ${CLOCK_DEFAULT})"
TIMEZONE="$(kernel_cmdline timezone ${TIMEZONE_DEFAULT})"
KEYMAP="$(kernel_cmdline keymap ${KEYMAP_DEFAULT})"
CONSOLEFONT="$(kernel_cmdline consolefont ${CONSOLEFONT_DEFAULT})"
CONSOLEMAP="$(kernel_cmdline consolemap ${CONSOLEMAP_DEFAULT})"
USECOLOR="$(kernel_cmdline usecolor ${USECOLOR_DEFAULT})"

MODULES=()

UDEV_TIMEOUT=30
USEDMRAID="no"
USEBTRFS="no"
USELVM="no"

HOSTNAME="archiso"

DAEMONS=(hwclock syslog-ng)

interface=eth0
address=192.168.0.99
netmask=255.255.255.0
broadcast=192.168.0.255
gateway=192.168.0.1

rc.conf 後

#
# /etc/rc.conf - Main Configuration for Arch Linux

. /etc/archiso/functions

LOCALE_DEFAULT="en_US.UTF-8"
DAEMON_LOCALE_DEFAULT="no"
CLOCK_DEFAULT="UTC"
TIMEZONE_DEFAULT="Canada/Pacific"
KEYMAP_DEFAULT="us"
CONSOLEFONT_DEFAULT=
CONSOLEMAP_DEFAULT=
USECOLOR_DEFAULT="yes"

LOCALE="$(kernel_cmdline locale ${LOCALE_DEFAULT})"
DAEMON_LOCALE="$(kernel_cmdline daemon_locale ${DAEMON_LOCALE_DEFAULT})"
HARDWARECLOCK="$(kernel_cmdline clock ${CLOCK_DEFAULT})"
TIMEZONE="$(kernel_cmdline timezone ${TIMEZONE_DEFAULT})"
KEYMAP="$(kernel_cmdline keymap ${KEYMAP_DEFAULT})"
CONSOLEFONT="$(kernel_cmdline consolefont ${CONSOLEFONT_DEFAULT})"
CONSOLEMAP="$(kernel_cmdline consolemap ${CONSOLEMAP_DEFAULT})"
USECOLOR="$(kernel_cmdline usecolor ${USECOLOR_DEFAULT})"

MODULES=()

UDEV_TIMEOUT=30
USEDMRAID="no"
USEBTRFS="no"
USELVM="no"

HOSTNAME="archiso"

DAEMONS=(hwclock syslog-ng)

interface=eth0 
interface=eth0
address=1.1.1.1
address=192.168.0.99
netmask=3.3.3.3
netmask=255.255.255.0
broadcast=2.2.2.2
broadcast=192.168.0.255
gateway=4.4.4.4
4

2 に答える 2

1

問題はあなたのif/ if/ / / /チェーンです。これは/ / if/ if/ if/elseチェーンでなければなりません。、などに一致するものを含む、一致しないすべての行のトリガー。ifelsifelsifelsifelsifelseelse { print OS $_ }gateway=interfaceaddress

于 2012-05-02T14:43:26.480 に答える
1

私はあなたのスクリプトの残りの部分についてコメントするつもりはありませんが、次のようになります。

if (system ("cat","/etc/rc.conf","|","grep","interface")){ 

システム0は成功時に戻ります。

systemそのため、その呼び出しが失敗した場合にのみブロックに入ります。

実際、私は現在Windowsシステムを使用しています/etc/rc.confが、 Cygwincatgrep感謝します。次のスクリプトを実行しています:

#!/usr/bin/env perl

use strict; use warnings;

if (system ("cat","/etc/rc.conf","|","grep","interface")){
    print "*** it worked! ***\n";
    if ($? == -1) {
        print "failed to execute: $!\n";
    }
    elsif ($? & 127) {
        printf "child died with signal %d, %s coredump\n",
            ($? & 127),  ($? & 128) ? 'with' : 'without';
    }
    else {
        printf "child exited with value %d\n", $? >> 8;
    }
}

出力を生成します:

cat: /etc/rc.conf: そのようなファイルまたはディレクトリはありません
cat: |: そのようなファイルまたはディレクトリはありません
cat: grep: そのようなファイルまたはディレクトリはありません
cat: インターフェイス: そのようなファイルやディレクトリはありません
*** 出来た!***
子は値 1 で終了しました

つまりsystem、失敗コードが返されました。ここで、シェルのパイピングとリダイレクトを使用する場合systemは、リストではなく文字列を渡し、次のようにチェックする必要があります。

if (system ('cat /etc/rc.conf | grep interface') == 0) {

一方で、終了ステータスを伝播するシェルを信頼したくありません。

以下は、より良い方向を示しているはずです。

#!/usr/bin/env perl

use strict;use warnings;

my %lookup = (
    eth0 => {
        address => '1.1.1.1',
        broadcast => '2.2.2.2',
        netmask => '3.3.3.3',
        gateway => '4.4.4.4',
    },
    wlan0 => {
        address => '5.5.5.5',
        broadcast => '6.6.6.6',
        netmask => '7.7.7.7',
        gateway => '8.8.8.8',
    },

);

while (my $line = <DATA>) {
    if (my ($interface) = ($line =~ /^interface=(\S+)/)) {
        print $line;
        if (exists $lookup{$interface}) {
            $line = process_interface(\*DATA, $lookup{$interface});
            redo;
        }
    }
    else {
        print $line;
    }
}

sub process_interface {
    my ($fh, $lookup) = @_;
    my $keys = join '|', sort keys %$lookup;

    while (my $line = <DATA>) {
        $line =~ s/\A($keys)=.+/$1=$lookup->{$1}/
            or return $line;
        print $line;
    }

    return;
}

__DATA__
#
# /etc/rc.conf - Main Configuration for Arch Linux

. /etc/archiso/functions

# stuff

interface=eth0
address=192.168.0.99
netmask=255.255.255.0
broadcast=192.168.0.255
gateway=192.168.0.1
interface=wlan0
address=192.168.0.99
netmask=255.255.255.0
broadcast=192.168.0.255
gateway=192.168.0.1

出力:

#
# /etc/rc.conf - Arch Linux のメイン設定

. /etc/archiso/関数

# もの

インターフェース=eth0
アドレス=1.1.1.1
ネットマスク=3.3.3.3
ブロードキャスト=2.2.2.2
ゲートウェイ=4.4.4.4
インターフェース=wlan0
アドレス=5.5.5.5
ネットマスク=7.7.7.7
ブロードキャスト=6.6.6.6
ゲートウェイ=8.8.8.8
于 2012-05-02T14:44:29.377 に答える