]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Document how to internationalize shell scripts.
authorBruno Haible <bruno@clisp.org>
Wed, 17 Sep 2003 08:28:30 +0000 (08:28 +0000)
committerBruno Haible <bruno@clisp.org>
Tue, 23 Jun 2009 10:10:59 +0000 (12:10 +0200)
gettext-tools/doc/ChangeLog
gettext-tools/doc/Makefile.am
gettext-tools/doc/gettext.texi

index 7d4196328baf44619113d369e44d294eb58cd334..5058d68d416cab72f4ca546de1724ac81ca055e2 100644 (file)
@@ -1,3 +1,16 @@
+2003-09-13  Bruno Haible  <bruno@clisp.org>
+
+       * gettext.texi: Update menus.
+       (sh): Update.
+       (Preparing Shell Scripts, gettext.sh, gettext Invocation,
+       ngettext Invocation, envsubst Invocation, eval_gettext Invocation,
+       eval_ngettext Invocation): New subsubsections.
+       * Makefile.am (TEXINCLUDES): New variable.
+       (gettext_TEXINFOS): Add the files from gettext-runtime/doc/.
+       (MAKEINFOFLAGS, TEXI2DVI): New variables, needed for TEXINCLUDES.
+       (TEXI2PDF): Add TEXINCLUDES.
+       (gettext.html, gettext_toc.html): Use TEXINCLUDES.
+
 2003-09-13  Bruno Haible  <bruno@clisp.org>
 
        * gettext.texi (sh-format): New subsection.
index 9147b9093d227dae234e9e2ef07baae6255fc354..cb55ffd63b26920328e68779233454cfea6acb82 100644 (file)
@@ -26,11 +26,13 @@ htmldir = $(docdir)
 AUTOMAKE_OPTIONS = 1.2 gnits
 EXTRA_DIST =
 MOSTLYCLEANFILES =
+TEXINCLUDES = -I $(top_srcdir)/../gettext-runtime/doc
 
 SED = sed
 RM = rm -f
 
 MAKEINFO = env LANG= LANGUAGE= @MAKEINFO@
+MAKEINFOFLAGS = $(TEXINCLUDES)
 
 info_TEXINFOS = gettext.texi
 # List of texinfo sources @included by gettext.texi, excluding version.texi.
@@ -38,7 +40,10 @@ gettext_TEXINFOS = \
   xgettext.texi msginit.texi msgmerge.texi msgcat.texi msgconv.texi \
   msggrep.texi msgfilter.texi msguniq.texi msgcomm.texi msgcmp.texi \
   msgattrib.texi msgen.texi msgexec.texi msgfmt.texi msgunfmt.texi \
-  gettextize.texi autopoint.texi iso-639.texi iso-3166.texi
+  gettextize.texi autopoint.texi iso-639.texi iso-3166.texi \
+  $(top_srcdir)/../gettext-runtime/doc/rt-gettext.texi \
+  $(top_srcdir)/../gettext-runtime/doc/rt-ngettext.texi \
+  $(top_srcdir)/../gettext-runtime/doc/rt-envsubst.texi
 
 EXTRA_DIST += \
   iso-639.sed iso-3166.sed ISO_639 ISO_3166 ISO_3166_de texi2html \
@@ -95,6 +100,8 @@ MAINTAINERCLEANFILES = gettext_*.html
 
 # Documentation in DVI format.
 
+TEXI2DVI = texi2dvi $(TEXINCLUDES)
+
 install-dvi: gettext.dvi
        $(mkinstalldirs) $(DESTDIR)$(dvidir)
        $(INSTALL_DATA) `if test -f gettext.dvi; then echo .; else echo $(srcdir); fi`/gettext.dvi $(DESTDIR)$(dvidir)/gettext.dvi
@@ -141,7 +148,7 @@ uninstall-ps:
 
 # Documentation in Portable Document Format.
 
-TEXI2PDF = @TEXI2PDF@
+TEXI2PDF = @TEXI2PDF@ $(TEXINCLUDES)
 SUFFIXES = .pdf
 
 pdf: gettext.pdf
@@ -169,14 +176,14 @@ html-monolithic: gettext.html
 html-split: gettext_toc.html
 
 gettext.html: gettext.texi version.texi $(gettext_TEXINFOS)
-       $(TEXI2HTML) -expandinfo -number -monolithic `if test -f gettext.texi; then echo gettext.texi; else echo $(srcdir)/gettext.texi; fi`
+       $(TEXI2HTML) $(TEXINCLUDES) -expandinfo -number -monolithic `if test -f gettext.texi; then echo gettext.texi; else echo $(srcdir)/gettext.texi; fi`
 
 gettext_toc.html: gettext.texi version.texi $(gettext_TEXINFOS)
        case "@PERL@" in \
          *"/missing perl") \
-            $(TEXI2HTML) -expandinfo -number -split_chapter `if test -f gettext.texi; then echo gettext.texi; else echo $(srcdir)/gettext.texi; fi` || exit 0 ;; \
+            $(TEXI2HTML) $(TEXINCLUDES) -expandinfo -number -split_chapter `if test -f gettext.texi; then echo gettext.texi; else echo $(srcdir)/gettext.texi; fi` || exit 0 ;; \
          *) $(RM) gettext_*.html ; \
-            $(TEXI2HTML) -expandinfo -number -split_chapter `if test -f gettext.texi; then echo gettext.texi; else echo $(srcdir)/gettext.texi; fi` ;; \
+            $(TEXI2HTML) $(TEXINCLUDES) -expandinfo -number -split_chapter `if test -f gettext.texi; then echo gettext.texi; else echo $(srcdir)/gettext.texi; fi` ;; \
        esac
 
 install-html-monolithic: gettext.html
index 164560df4228097729a978798c3a98ee90030366..207da1108c5c980e027bd6fb97c2d1c2a8032ad2 100644 (file)
@@ -364,6 +364,28 @@ Individual Programming Languages
 * Pike::                        Pike
 * GCC-source::                  GNU Compiler Collection sources
 
+sh - Shell Script
+
+* Preparing Shell Scripts::     Preparing Shell Scripts for Internationalization
+* gettext.sh::                  Contents of @code{gettext.sh}
+* gettext Invocation::          Invoking the @code{gettext} program
+* ngettext Invocation::         Invoking the @code{ngettext} program
+* envsubst Invocation::         Invoking the @code{envsubst} program
+* eval_gettext Invocation::     Invoking the @code{eval_gettext} function
+* eval_ngettext Invocation::    Invoking the @code{eval_ngettext} function
+
+Perl
+
+* General Problems::            General Problems Parsing Perl Code
+* Default Keywords::            Which Keywords Will xgettext Look For?
+* Special Keywords::            How to Extract Hash Keys
+* Quote-like Expressions::      What are Strings And Quote-like Expressions?
+* Interpolation I::             Invalid String Interpolation
+* Interpolation II::            Valid String Interpolation
+* Parentheses::                 When To Use Parentheses
+* Long Lines::                  How To Grok with Long Lines
+* Perl Pitfalls::               Bugs, Pitfalls, and Things That Do Not Work
+
 Internationalizable Data
 
 * POT::                         POT - Portable Object Template
@@ -7438,7 +7460,7 @@ that language, and to combine the resulting files using @code{msgcat}.
 @c   Java                    1200     *
 @c   PHP                     1051     *
 @c   Python                   613     *
-@c   Unix Shell               357
+@c   Unix Shell               357     *
 @c   Tcl                      266     *
 @c   SQL                      174
 @c   JavaScript               118
@@ -7574,12 +7596,13 @@ bash, gettext
 @code{"abc"}, @code{'abc'}, @code{abc}
 
 @item gettext shorthand
-@code{"`gettext "abc"`"}
+@code{"`gettext \"abc\"`"}
 
 @item gettext/ngettext functions
 @pindex gettext
 @pindex ngettext
 @code{gettext}, @code{ngettext} programs
+@*@code{eval_gettext}, @code{eval_ngettext} shell functions
 
 @item textdomain
 @vindex TEXTDOMAIN@r{, environment variable}
@@ -7593,75 +7616,212 @@ environment variable @code{TEXTDOMAINDIR}
 automatic
 
 @item Prerequisite
----
+@code{. gettext.sh}
 
 @item Use or emulate GNU gettext
 use
 
 @item Extractor
----
+@code{xgettext}
 
 @item Formatting with positions
 ---
 
 @item Portability
----
+fully portable
 
 @item po-mode marking
 ---
 @end table
 
-@node bash, Python, sh, List of Programming Languages
-@subsection bash - Bourne-Again Shell Script
-@cindex bash
+@menu
+* Preparing Shell Scripts::     Preparing Shell Scripts for Internationalization
+* gettext.sh::                  Contents of @code{gettext.sh}
+* gettext Invocation::          Invoking the @code{gettext} program
+* ngettext Invocation::         Invoking the @code{ngettext} program
+* envsubst Invocation::         Invoking the @code{envsubst} program
+* eval_gettext Invocation::     Invoking the @code{eval_gettext} function
+* eval_ngettext Invocation::    Invoking the @code{eval_ngettext} function
+@end menu
 
-@table @asis
-@item RPMs
-bash 2.0 or newer, gettext
+@node Preparing Shell Scripts, gettext.sh, sh, sh
+@subsubsection Preparing Shell Scripts for Internationalization
+@cindex preparing shell scripts for translation
 
-@item File extension
-@code{sh}
+Preparing a shell script for internationalization is conceptually similar
+to the steps described in @ref{Sources}.  The concrete steps for shell
+scripts are as follows.
 
-@item String syntax
-@code{"abc"}, @code{'abc'}, @code{abc}
+@enumerate
+@item
+Insert the line
 
-@item gettext shorthand
-@code{$"abc"}
+@smallexample
+. gettext.sh
+@end smallexample
 
-@item gettext/ngettext functions
-@pindex gettext
-@pindex ngettext
-@code{gettext}, @code{ngettext} programs
+near the top of the script.  @code{gettext.sh} is a shell function library
+that provides the functions
+@code{eval_gettext} (see @ref{eval_gettext Invocation}) and
+@code{eval_ngettext} (see @ref{eval_ngettext Invocation}).
+You have to ensure that @code{gettext.sh} can be found in the @code{PATH}.
 
-@item textdomain
-@vindex TEXTDOMAIN@r{, environment variable}
-environment variable @code{TEXTDOMAIN}
+@item
+Set and export the @code{TEXTDOMAIN} and @code{TEXTDOMAINDIR} environment
+variables.  Usually @code{TEXTDOMAIN} is the package or program name, and
+@code{TEXTDOMAINDIR} is the absolute pathname corresponding to
+@code{$prefix/share/locale}, where @code{$prefix} is the installation location.
 
-@item bindtextdomain
-@vindex TEXTDOMAINDIR@r{, environment variable}
-environment variable @code{TEXTDOMAINDIR}
+@smallexample
+TEXTDOMAIN=@@PACKAGE@@
+export TEXTDOMAIN
+TEXTDOMAINDIR=@@LOCALEDIR@@
+export TEXTDOMAINDIR
+@end smallexample
 
-@item setlocale
-automatic
+@item
+Prepare the strings for translation, as described in @ref{Preparing Strings}.
 
-@item Prerequisite
----
+@item
+Simplify translatable strings so that they don't contain command substitution
+(@code{"`...`"} or @code{"$(...)"}), variable access with defaulting (like
+@code{$@{@var{variable}-@var{default}@}}), access to positional arguments
+(like @code{$0}, @code{$1}, ...) or highly volatile shell variables (like
+@code{$?}). This can always be done through simple local code restructuring.
+For example,
 
-@item Use or emulate GNU gettext
-use
+@smallexample
+echo "Usage: $0 [OPTION] FILE..."
+@end smallexample
 
-@item Extractor
-@code{bash --dump-po-strings}
+becomes
 
-@item Formatting with positions
----
+@smallexample
+program_name=$0
+echo "Usage: $program_name [OPTION] FILE..."
+@end smallexample
 
-@item Portability
----
+Similarly,
 
-@item po-mode marking
----
-@end table
+@smallexample
+echo "Remaining files: `ls | wc -l`"
+@end smallexample
+
+becomes
+
+@smallexample
+filecount="`ls | wc -l`"
+echo "Remaining files: $filecount"
+@end smallexample
+
+@item
+For each translatable string, change the output command @samp{echo} or
+@samp{$echo} to @samp{gettext} (if the string contains no references to
+shell variables) or to @samp{eval_gettext} (if it refers to shell variables),
+followed by a no-argument @samp{echo} command (to account for the terminating
+newline). Similarly, for cases with plural handling, replace a conditional
+@samp{echo} command with an invocation of @samp{ngettext} or
+@samp{eval_ngettext}, followed by a no-argument @samp{echo} command.
+@end enumerate
+
+@node gettext.sh, gettext Invocation, Preparing Shell Scripts, sh
+@subsubsection Contents of @code{gettext.sh}
+
+@code{gettext.sh}, contained in the run-time package of GNU gettext, provides
+the following:
+
+@itemize @bullet
+@item $echo
+The variable @code{echo} is set to a command that outputs its first argument
+and a newline, without interpreting backslashes in the argument string.
+
+@item eval_gettext
+See @ref{eval_gettext Invocation}.
+
+@item eval_ngettext
+See @ref{eval_ngettext Invocation}.
+@end itemize
+
+@node gettext Invocation, ngettext Invocation, gettext.sh, sh
+@subsubsection Invoking the @code{gettext} program
+
+@include rt-gettext.texi
+
+@node ngettext Invocation, envsubst Invocation, gettext Invocation, sh
+@subsubsection Invoking the @code{ngettext} program
+
+@include rt-ngettext.texi
+
+@node envsubst Invocation, eval_gettext Invocation, ngettext Invocation, sh
+@subsubsection Invoking the @code{envsubst} program
+
+@include rt-envsubst.texi
+
+@node eval_gettext Invocation, eval_ngettext Invocation, envsubst Invocation, sh
+@subsubsection Invoking the @code{eval_gettext} function
+
+@cindex @code{eval_gettext} function, usage
+@example
+eval_gettext @var{msgid}
+@end example
+
+@cindex lookup message translation
+This function outputs the native language translation of a textual message,
+performing dollar-substitution on the result.  Note that only shell variables
+mentioned in @var{msgid} will be dollar-substituted in the result.
+
+@node eval_ngettext Invocation,  , eval_gettext Invocation, sh
+@subsubsection Invoking the @code{eval_ngettext} function
+
+@cindex @code{eval_ngettext} function, usage
+@example
+eval_ngettext @var{msgid} @var{msgid-plural} @var{count}
+@end example
+
+@cindex lookup plural message translation
+This function outputs the native language translation of a textual message
+whose grammatical form depends on a number, performing dollar-substitution
+on the result.  Note that only shell variables mentioned in @var{msgid} or
+@var{msgid-plural} will be dollar-substituted in the result.
+
+@node bash, Python, sh, List of Programming Languages
+@subsection bash - Bourne-Again Shell Script
+@cindex bash
+
+GNU @code{bash} 2.0 or newer has a special shorthand for translating a
+string and substituting variable values in it: @code{$"msgid"}.  But
+the use of this construct is @strong{discouraged}, due to the security
+holes it opens and due to its portability problems.
+
+The security holes of @code{$"..."} come from the fact that after looking up
+the translation of the string, @code{bash} processes it like it processes
+any double-quoted string: dollar and backquote processing, like @samp{eval}
+does.
+
+@enumerate
+@item
+In a locale whose encoding is one of BIG5, BIG5-HKSCS, GBK, GB18030, SHIFT_JIS,
+JOHAB, some double-byte characters have a second byte whose value is
+@code{0x60}.  For example, the byte sequence @code{\xe0\x60} is a single
+character in these locales.  Many versions of @code{bash} (all versions
+up to bash-2.05, and newer versions on platforms without @code{mbsrtowcs()}
+function) don't know about character boundaries and see a backquote character
+where there is only a particular Chinese character.  Thus it can start
+executing part of the translation as a command list.  This situation can occur
+even without the translator being aware of it: if the translator provides
+translations in the UTF-8 encoding, it is the @code{gettext()} function which
+will, during its conversion from the translator's encoding to the user's
+locale's encoding, produce the dangerous @code{\x60} bytes.
+
+@item
+A translator could - voluntarily or inadvertantly - use backquotes
+@code{"`...`"} or dollar-parentheses @code{"$(...)"} in her translations.
+The enclosed strings would be executed as command lists by the shell.
+@end enumerate
+
+The portability problem is that @code{bash} must be built with
+internationalization support; this is normally not the case on systems
+that don't have the @code{gettext()} function in libc.
 
 @node Python, Common Lisp, bash, List of Programming Languages
 @subsection Python
@@ -8443,15 +8603,15 @@ the other backends but it also has some Perl specific limitations, the
 worst probably being its imperfectness.
 
 @menu
-* General Problems::         General Problems Parsing Perl Code
-* Default Keywords::         Which Keywords Will xgettext Look For?
-* Special Keywords::         How to Extract Hash Keys
-* Quote-like Expressions::   What are Strings And Quote-like Expressions?
-* Interpolation I::          Invalid String Interpolation
-* Interpolation II::         Valid String Interpolation
-* Parentheses::              When To Use Parentheses
-* Long Lines::               How To Grok with Long Lines
-* Perl Pitfalls::            Bugs, Pitfalls, and Things That Do Not Work
+* General Problems::            General Problems Parsing Perl Code
+* Default Keywords::            Which Keywords Will xgettext Look For?
+* Special Keywords::            How to Extract Hash Keys
+* Quote-like Expressions::      What are Strings And Quote-like Expressions?
+* Interpolation I::             Invalid String Interpolation
+* Interpolation II::            Valid String Interpolation
+* Parentheses::                 When To Use Parentheses
+* Long Lines::                  How To Grok with Long Lines
+* Perl Pitfalls::               Bugs, Pitfalls, and Things That Do Not Work
 @end menu
 
 @node General Problems, Default Keywords,  , Perl