通过管道向perl脚本传入参数
echo "abc" | test.pltest.pl只是一个简单的输出输入参数的script,使用$ARGV[0,但是这样的命令不能够得到参数"abc"。应该怎么写程序可以获得外部从管道传入的参数值呢,perl命令行下是可以的:
echo "abc" | perl -e '$tem = <STDIN>; print $tem;'
当向perl脚本使用管道传参就需要处理一下:
#!/usr/bin/perl
use Data::Dumper;
my @input;
#取得当前的绝对路径
my $abpath="$ENV{PWD}";
while($_=<STDIN>){
if($_=~/\\q$/){
last;
}else{
push (@input,$_);
}
}
print Dumper(\@input);
#当输入'\q'时,表示退出。
$ echo "bac 123 freeoa"|/tmp/pipoin.pl
$VAR1 = [
'bac 123 freeoa'
];
下面是一个nagios下通过perl脚本向xmpp服务器发送信息的代码片断。
#消息发送程序载入
sub sndims{
my $mesage="";
$mesage=shift @_;
my @atargs=("/home/freeoa/bin/nxmp.pl","$mesage");
system(@atargs)==0 or die "system @atargs failed:$!";
}
sndims("@input");
'/home/freeoa/bin/nxmp.pl'就是可以通过管道传入值并处理的脚本。
在Shell环境中传入变量参数
for d in 1 2 3; do perl -se 'print "$sp"' -- -sp=$d; done
亦可读取环境变量中设定
export MYVAR='freeoa'
perl -e 'print $ENV{MYVAR}'
#!/bin/bash
file=$1
var=$2
cat $file | perl -e 'BEGIN { $var = $ARGV[0] } print <STDIN>' $var
#!/bin/bash
file="timer"
var="Two"
(echo $var; cat $file) | perl -e 'BEGIN { $var=<> } print <>; END { print $var }'
perl -sE 'say $foo' -- -foo=$MYVAR
perl -se 'print "$foo\n" if $foo' -- -foo=$MYVAR
perl -le 'print shift' foo
上文的传参基本上的是英文情况的,那对多字节(如中文)的参数传递和处理情况呢,事实上在命令行的传参上没有想象中那么难或容易,尽管当前的终端的编码是utf8。具体更多信息请参见《Perl命令行应用介绍》的'-C'选项及"Unicode属性支持"小节。下面提供一个简单的示例:
$ perl -CA freeoa.pl 阆中牛肉面
----------------
freeoa.pl
use v5.32;
use utf8;
binmode(STDIN, ':encoding(utf8)');
binmode(STDOUT, ':encoding(utf8)');
my $hstr=shift @ARGV;
say 'hstr:'.$hstr;
ucp5($hstr);
sub ucp5 {
my $r=shift;
#say 'R in:',$r;
$r=utf8::is_utf8($r) ? $r : utf8::decode($r);
if(utf8::is_utf8($r)){
say 'str in utf8.';
}else{
say 'str Not utf8!';
}
for my $ucp_num (unpack('W*', $r)) {
say sprintf("%04X", $ucp_num);
}
}
----------------
perl script get arguments and encode or decode
perl脚本对获取的参数进行编码与解码
Perl v5.6之前,Unicode编码形式都不能得到良好支持,v5.12很多时候被认为是最低安全标准的版本;v5.14相较于其它编程语言提供了对Unicode一定程序上的支持。UTF-8与ASCII是兼容的,因此UTF-8成为Unicode主流的编码方式。Perl早期版本中,当使用lc,uc的时候,在128~255间的字符常会出现异常情况。
在命令行终端下,perl获取从终端传入的非英文语系的多字节参数相关说明。stackoverflow的此文可以参考;外部数据源在Perl中进行处理很棘手。对于命令行参数,您可能会将它们作为在您的区域设置中指定的编码获取;不要依赖于你的语言环境与其他可能运行你的脚本的人的语言环境相同。你必须找出它是什么,然后转换成Perl的内部格式。幸运的是,这并不难。可在此查询。
The I18N::Langinfo module has the stuff you need to get the encoding:
use I18N::Langinfo qw(langinfo CODESET);
my $codeset = langinfo(CODESET);
Once you know the encoding, you can decode them to Perl strings:
use Encode qw(decode);
@ARGV = map { decode $codeset, $_ } @ARGV;
尽管Perl将内部字符串编码为UTF-8,但您不应该考虑或了解这一点。你只需要解码你得到的任何东西,这会把它变成Perl的内部表示。相信Perl会处理其他所有事情。当需要存储数据时,请确保使用合理的编码。如果知道当前所设置是UTF-8,并且终端将给予UTF-8的命令行参数,那么可以使用带有Perl的-C开关的A选项。这告诉你的程序假设参数被编码为UTF-8:
perl -CA program
安装Encode::Locale模块并使用之
use Encode::Locale;
decode_argv Encode::FB_CROAK;
不需要对字符串做任何特殊的处理。从Perl v5.8开始,字符串默认为UTF-8。
Unicode Code Point:SNOWMAN的HEX值为2603,perl中可写为:\x{2603}或\N{U+2603}
perl -CO -le 'print "\x{2603}"' | xargs perl -le 'print "I saw @ARGV"'
The code above works just fine on Ubuntu 9.04, OS X 10.6, and FreeBSD 7.
另外发现一个问题:终端对符号型unicode码的显示问题,在xshell上只有有特写的字体且字号在16以上才可以看全,而在linux的桌面终端上则没有此问题。
perl -Mutf8 -wle ';print utf8::is_utf8($ARGV[0]) ? "t" : "f"' a
or
perl -Mutf8 -CA -wle ';print utf8::is_utf8($ARGV[0]) ? "t" : "f"' a
更多参考:
Perl Unicode Cookbook: The Standard Preamble
perlrun
参考来源:
perl脚本中的重定向
该文章最后由 阿炯 于 2024-05-30 14:19:34 更新,目前是第 2 版。