有没有一种方法可以检查参数是否用单引号传递?

4

有没有一种(最好的)方法来检查,如果$uri被传递在单引号中?

#!/usr/local/bin/perl
use warnings;
use 5.012;

my $uri = shift;
# uri_check
# ...

为了更清晰地阐述我的问题,我添加了这个例子。

#!/usr/local/bin/perl
use warnings;
use 5.012;
use URI;
use URI::Escape;
use WWW::YouTube::Info::Simple;
use Term::Clui;

my $uri = shift;
# uri check here

$uri = URI->new( $uri );
my %params = $uri->query_form;
die "Malformed URL or missing parameter" if $params{v} eq '';
my $video_id = uri_escape( $params{v} );

my $yt = WWW::YouTube::Info::Simple->new( $video_id );
my $info = $yt->get_info();

my $res = $yt->get_resolution();
my @resolution;
for my $fmt ( sort { $a <=> $b }  keys %$res ) {
    push @resolution,  sprintf "%d : %s", $fmt, $res->{$fmt};

}

# with an uri-argument which is not passed in single quotes 
# the script doesn't get this far

my $fmt = choose( 'Resolution', @resolution );
$fmt = ( split /\s:\s/, $fmt )[0];
say $fmt; 

当我这样调用你的程序:perl so6249816.pl http://www.youtube.com/watch?v=TkqgnVW2_aA(注意,没有任何shell引用),它确实会一直执行到第27行及其后面。你源代码中的注释说不会这样,解释一下这个矛盾之处。 - daxim
当我从YouTube视频复制一个“视频URL”时,我得到的格式是这样的http://www.youtube.com/watch?v=BzSTSkhBCOc&feature=player_detailpage,如果不加引号,它在我的尝试中无法工作。 - sid_com
2个回答

12

你无法这样做;bash在将字符串传递给Perl解释器之前就会解析引号。


2
@Grrrr:我说bash是因为它在问题的标签中。 - Blagovest Buyukliev
4
@sid_com,看起来很明显这是一个“XY问题”(http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem),因此更好的问题是:“为什么你认为知道如何引用shell参数将帮助你解决实际问题(未说明的)?”换句话说,你认为自己为什么需要知道它是如何引用的? - tadmc
一个关于引号的错误信息会很好,因为我不知道下次使用脚本时会记得什么。 - sid_com

4

对Blagovest的答案进行补充:

perl程序 http://example.com/foo?bar=23&thing=42 被shell解释为:

  1. 执行perl并传递参数programhttp://example.com/foo?bar=23
  2. 将其在后台运行(这就是&的含义)
  3. thing=42解释为将环境变量thing设置为42

你应该看到一个错误,像-bash: thing: command not found但在这种情况下,bash将thing=42解释为有效指令。

Shell处理引号和Perl对此一无所知。Perl不能发出错误消息,它只能在shell处理后看到参数。它甚至看不到&。这只是Unix中你必须学会应对的事情之一。无论好坏,shell都是一个完整的编程环境。

还有其他简化了很多东西的shell,可以避免此问题,但是真正理解一个真实的shell的怪癖和功能才是更好的选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接