mldvx4 has asked for the wisdom of the Perl Monks concerning the following question:

I notice that /dev/stdout is not available to all users on some systems.

#!/usr/bin/perl use utf8; use strict; use warnings; open (OUT, ">:utf8", '/dev/stdout') or die("Could not open file 'stdout' : error: $!\n"); print OUT "åäöfoo\n"; close(OUT);

I am hoping to find a work-around or even a correct solution. The following only functions when use strict; has been removed.

#!/usr/bin/perl use utf8; use strict; use warnings; open (OUT, ">:utf8", STDOUT) or die("Could not open file 'stdout' : error: $!\n"); print OUT "åäöfoo\n"; close(OUT);

What would be the right approach to implement similar results?

Replies are listed 'Best First'.
Re: Forcing UTF-8 output on STDOUT
by choroba (Cardinal) on Feb 10, 2021 at 19:36 UTC
    Do you really want to send the output to a file named STDOUT?

    If not, use binmode instead of open:

    #!/usr/bin/perl use utf8; use strict; use warnings; binmode *STDOUT, ':utf8'; print "åäöfoo\n";

    Using :encoding(UTF-8) instead of :utf8 would turn on some useful checking, too.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

      The following would also do the trick:

      use open ':std', ':encoding(UTF-8)';

      It adds the encoding layer to STDIN, STDOUT and STDERR, it does so at compile time, and it sets the default encoding for open in scope.

      Seeking work! You can reach me at ikegami@adaelis.com

      Thanks. I had experimented with binmode in different ways, but your example does the job!

      Thanks.
      "Do you really want to send the output to a file named STDOUT?"

      Not really. What I was trying to do is have a medium-sized script be able to alternate between writing output to a file or to stdout itself, depending on an option.

      . . . if (defined($opt{'o'})) { $output = $opt{'o'}; $output =~ s/[\0-\x1f]//g; if ($output =~ /^([-\/\w\.]+)$/) { $output = $1; } else { die("Bad path or file name: '$output'\n"); } } else { $output = '/dev/stdout'; } . . . open(my $out, $mode, $output) or die("Could not open '$output' for writing: $!\n");
      That way I can use the same print statements for either purpose. I presume there is a better way for all that, however.
        > alternate between writing output to a file or to stdout itself

        select?

        map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
      A reply falls below the community's threshold of quality. You may see it by logging in.