从perl的子进程获取UTF字符串

时间:2016-08-22 06:27:21

标签: perl utf-8

我正在研究一个简单的脚本,该脚本在Ubuntu Linux(版本16.04中获取和设置背景,但在这种情况下无关紧要)。问题是我的文件夹名称是UTF-8编码的(特别是中文)。因此,获取当前壁纸的路径失败,如下所示:

my $user_background=qx/gsettings get org.gnome.desktop.background picture-uri/;

print $user_background的输出:

file:///home/xieerqi/%E4%B8%8B%E8%BD%BD/testimage.jpg

因此,问题是:如何从perl中的shell命令获取正确编码/解码的字符串

我试过这个:

my $unicode_String=Encode::decode('utf-8', $user_background );

哪个不起作用。

添加binmode(STDOUT,":utf8");也无济于事

添加use utf8;无效

奇怪的是,使用相同的字符串来设置背景确实有效。

3 个答案:

答案 0 :(得分:4)

这对我来说是正确的。字符已经过UTF-8编码,然后进行URL编码,因此URL应该正确识别文件。你不应该期望能够阅读它

字符串%E4%B8%8B%E8%BD%BD对应

- `E4 B8 8B`, which is the character U+4E0B or 下

- `E8 BD BD`, which is the character U+8F7D or 载

下载是“下载”。是吗?

你真的想用字符串做什么?如果您使用picture-filename而不是picture-uri

,您可能会获得可读性

答案 1 :(得分:4)

听起来您想要从网址中提取路径。

use open ':std', ':locale';
use feature qw( say );

use Encode      qw( decode_utf8 );
use URI         qw( );
use URI::Escape qw( uri_unescape );

my $url = URI->new('file:///home/xieerqi/%E4%B8%8B%E8%BD%BD/testimage.jpg');

$url->scheme eq 'file'
   or die("Invalid input\n");

my $path = decode_utf8( uri_unescape( $url->path ) );

say $path;

作为一个单行:

perl -CS -MEncode=decode_utf8 -MURI -MURI::Escape=uri_unescape \
   -e'CORE::say( decode_utf8( uri_unescape( URI->new($ARGV[0])->path ) ) )' \
      file:///home/xieerqi/%E4%B8%8B%E8%BD%BD/testimage.jpg

由于上一个代码片段采用了UTF-8终端,我们不妨立即避免解码及其后的编码:

perl -MURI -MURI::Escape=uri_unescape \
   -e'CORE::say( uri_unescape( URI->new($ARGV[0])->path ) )' \
      file:///home/xieerqi/%E4%B8%8B%E8%BD%BD/testimage.jpg

答案 2 :(得分:0)

显然问题出在gsettings本身。即使在命令行上,它也返回相同的字符串,中文字符未解码。

$ gsettings get org.gnome.desktop.background picture-uri                                                                 
'file:///home/xieerqi/%E4%B8%8B%E8%BD%BD/ad32d5d0615e9572-121171d86d0c8618-e11082638606a82c303fee0b29697811.jpg'

即使强制环境,它也会返回相同的字符串

$ LC_ALL=C gsettings get org.gnome.desktop.background picture-uri                                                        
'file:///home/xieerqi/%E4%B8%8B%E8%BD%BD/ad32d5d0615e9572-121171d86d0c8618-e11082638606a82c303fee0b29697811.jpg'

然而,似乎使用decode_utf8()方法的子进程输出的正确方法是标量。基本上,这是我尝试过的,并成功获得输出

#!/usr/bin/env perl 

use strict;
use warnings;
use utf8;
use Encode;
my $stuff=qx/ls ~ /;
my $utf_string = decode_utf8( $stuff );
print "$utf_string";