Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does a colon as the entire first line mean?

Tags:

perl

I am trying to build the Apache OpenOffice source code in Cygwin on a Windows 8.1 system. The build fails with this message:

Entering /cygdrive/c/OpenOfficeDev/Trunk/main/solenv

/cygdrive/c/OpenOfficeDev/Trunk/main/solenv/bin/mkout.pl: line 1: $':\r': command not found
mkout -- version: 1.8 

The first few lines of mkout.pl are:

:
eval 'exec perl -wS $0 ${1+"$@"}'
    if 0;
#**************************************************************
#

I would like to understand what this means. Even good search terms would help.

like image 984
Patricia Shanahan Avatar asked Mar 14 '23 10:03

Patricia Shanahan


1 Answers

The problem is the \r (CR, Return) character.

The lines:

eval 'exec perl -wS $0 ${1+"$@"}'
    if 0;

indicate that the file mkout.pl is intended to be executed as a shell script, using a hack that causes the script to re-execute itself as a Perl script. This is common on systems that don't support Unix-style #! lines, but it works on Unix-like systems as well.

The : is a built-in shell command that does nothing.

The error message indicates that mkout.pl has Windows-style line endings. The shell (Cygwin's default shell is bash) doesn't handle Windows-style line endings, so when it sees a line consisting of the characters ':', '\r', and '\n', it interprets it as a command ":\r" followed by a newline. (It doesn't treat the '\r' character as whitespace.)

Modifying mkout.pl to use Unix-style line endings should solve the immediate problem -- but if it's part of the OpenOffice source distribution, there are going to be plenty of other files with the same issue. If you extracted the sources from a .zip file, be sure to unzip it in a way that doesn't convert text files.

(You could just install OpenOffice or LibreOffice in Windows, but I presume you have good reasons to build it from source under Cygwin. It's possible that OpenOffice doesn't support that particular environment.)

Once you get past that, there's still the question of what a : means in Perl. (Currently the Perl interpreter never gets to see your script.)

This is actually documented in perldoc perlrun, under the -S option (emphasis added):

This example works on many platforms that have a shell compatible with Bourne shell:

#!/usr/bin/perl
eval 'exec /usr/bin/perl -wS $0 ${1+"$@"}'
        if $running_under_some_shell;

The system ignores the first line and feeds the program to /bin/sh, which proceeds to try to execute the Perl program as a shell script. The shell executes the second line as a normal shell command, and thus starts up the Perl interpreter. On some systems $0 doesn't always contain the full pathname, so the -S tells Perl to search for the program if necessary. After Perl locates the program, it parses the lines and ignores them because the variable $running_under_some_shell is never true. If the program will be interpreted by csh, you will need to replace "${1+"$@"}" with $*, even though that doesn't understand embedded spaces (and such) in the argument list. To start up sh rather than csh, some systems may have to replace the "#!" line with a line containing just a colon, which will be politely ignored by Perl.

csh does recognize the : command. The csh man page on my system doesn't mention it, but the tcsh man page does:

: Does nothing, successfully.

(Unlike the : built-in in sh and bash, csh's : command doesn't accept arguments. tcsh corrects this.)

In any case, fixing the line endings should solve your problem.

like image 173
Keith Thompson Avatar answered Mar 15 '23 22:03

Keith Thompson