1@c This file is part of the GNU gettext manual. 2@c Copyright (C) 1995-2020 Free Software Foundation, Inc. 3@c See the file gettext.texi for copying conditions. 4 5@node sh 6@subsection sh - Shell Script 7@cindex shell scripts 8 9@table @asis 10@item RPMs 11bash, gettext 12 13@item Ubuntu packages 14bash, gettext-base 15 16@item File extension 17@code{sh} 18 19@item String syntax 20@code{"abc"}, @code{'abc'}, @code{abc} 21 22@item gettext shorthand 23@code{"`gettext \"abc\"`"} 24 25@item gettext/ngettext functions 26@pindex gettext 27@pindex ngettext 28@code{gettext}, @code{ngettext} programs 29@*@code{eval_gettext}, @code{eval_ngettext}, @code{eval_pgettext}, 30@code{eval_npgettext} shell functions 31 32@item textdomain 33@vindex TEXTDOMAIN@r{, environment variable} 34environment variable @code{TEXTDOMAIN} 35 36@item bindtextdomain 37@vindex TEXTDOMAINDIR@r{, environment variable} 38environment variable @code{TEXTDOMAINDIR} 39 40@item setlocale 41automatic 42 43@item Prerequisite 44@code{. gettext.sh} 45 46@item Use or emulate GNU gettext 47use 48 49@item Extractor 50@code{xgettext} 51 52@item Formatting with positions 53--- 54 55@item Portability 56fully portable 57 58@item po-mode marking 59--- 60@end table 61 62An example is available in the @file{examples} directory: @code{hello-sh}. 63 64@menu 65* Preparing Shell Scripts:: Preparing Shell Scripts for Internationalization 66* gettext.sh:: Contents of @code{gettext.sh} 67* gettext Invocation:: Invoking the @code{gettext} program 68* ngettext Invocation:: Invoking the @code{ngettext} program 69* envsubst Invocation:: Invoking the @code{envsubst} program 70* eval_gettext Invocation:: Invoking the @code{eval_gettext} function 71* eval_ngettext Invocation:: Invoking the @code{eval_ngettext} function 72* eval_pgettext Invocation:: Invoking the @code{eval_pgettext} function 73* eval_npgettext Invocation:: Invoking the @code{eval_npgettext} function 74@end menu 75 76@node Preparing Shell Scripts 77@subsubsection Preparing Shell Scripts for Internationalization 78@cindex preparing shell scripts for translation 79 80Preparing a shell script for internationalization is conceptually similar 81to the steps described in @ref{Sources}. The concrete steps for shell 82scripts are as follows. 83 84@enumerate 85@item 86Insert the line 87 88@smallexample 89. gettext.sh 90@end smallexample 91 92near the top of the script. @code{gettext.sh} is a shell function library 93that provides the functions 94@code{eval_gettext} (see @ref{eval_gettext Invocation}), 95@code{eval_ngettext} (see @ref{eval_ngettext Invocation}), 96@code{eval_pgettext} (see @ref{eval_pgettext Invocation}), and 97@code{eval_npgettext} (see @ref{eval_npgettext Invocation}). 98You have to ensure that @code{gettext.sh} can be found in the @code{PATH}. 99 100@item 101Set and export the @code{TEXTDOMAIN} and @code{TEXTDOMAINDIR} environment 102variables. Usually @code{TEXTDOMAIN} is the package or program name, and 103@code{TEXTDOMAINDIR} is the absolute pathname corresponding to 104@code{$prefix/share/locale}, where @code{$prefix} is the installation location. 105 106@smallexample 107TEXTDOMAIN=@@PACKAGE@@ 108export TEXTDOMAIN 109TEXTDOMAINDIR=@@LOCALEDIR@@ 110export TEXTDOMAINDIR 111@end smallexample 112 113@item 114Prepare the strings for translation, as described in @ref{Preparing Strings}. 115 116@item 117Simplify translatable strings so that they don't contain command substitution 118(@code{"`...`"} or @code{"$(...)"}), variable access with defaulting (like 119@code{$@{@var{variable}-@var{default}@}}), access to positional arguments 120(like @code{$0}, @code{$1}, ...) or highly volatile shell variables (like 121@code{$?}). This can always be done through simple local code restructuring. 122For example, 123 124@smallexample 125echo "Usage: $0 [OPTION] FILE..." 126@end smallexample 127 128becomes 129 130@smallexample 131program_name=$0 132echo "Usage: $program_name [OPTION] FILE..." 133@end smallexample 134 135Similarly, 136 137@smallexample 138echo "Remaining files: `ls | wc -l`" 139@end smallexample 140 141becomes 142 143@smallexample 144filecount="`ls | wc -l`" 145echo "Remaining files: $filecount" 146@end smallexample 147 148@item 149For each translatable string, change the output command @samp{echo} or 150@samp{$echo} to @samp{gettext} (if the string contains no references to 151shell variables) or to @samp{eval_gettext} (if it refers to shell variables), 152followed by a no-argument @samp{echo} command (to account for the terminating 153newline). Similarly, for cases with plural handling, replace a conditional 154@samp{echo} command with an invocation of @samp{ngettext} or 155@samp{eval_ngettext}, followed by a no-argument @samp{echo} command. 156 157When doing this, you also need to add an extra backslash before the dollar 158sign in references to shell variables, so that the @samp{eval_gettext} 159function receives the translatable string before the variable values are 160substituted into it. For example, 161 162@smallexample 163echo "Remaining files: $filecount" 164@end smallexample 165 166becomes 167 168@smallexample 169eval_gettext "Remaining files: \$filecount"; echo 170@end smallexample 171 172If the output command is not @samp{echo}, you can make it use @samp{echo} 173nevertheless, through the use of backquotes. However, note that inside 174backquotes, backslashes must be doubled to be effective (because the 175backquoting eats one level of backslashes). For example, assuming that 176@samp{error} is a shell function that signals an error, 177 178@smallexample 179error "file not found: $filename" 180@end smallexample 181 182is first transformed into 183 184@smallexample 185error "`echo \"file not found: \$filename\"`" 186@end smallexample 187 188which then becomes 189 190@smallexample 191error "`eval_gettext \"file not found: \\\$filename\"`" 192@end smallexample 193@end enumerate 194 195@node gettext.sh 196@subsubsection Contents of @code{gettext.sh} 197 198@code{gettext.sh}, contained in the run-time package of GNU gettext, provides 199the following: 200 201@itemize @bullet 202@item $echo 203The variable @code{echo} is set to a command that outputs its first argument 204and a newline, without interpreting backslashes in the argument string. 205 206@item eval_gettext 207See @ref{eval_gettext Invocation}. 208 209@item eval_ngettext 210See @ref{eval_ngettext Invocation}. 211 212@item eval_pgettext 213See @ref{eval_pgettext Invocation}. 214 215@item eval_npgettext 216See @ref{eval_npgettext Invocation}. 217@end itemize 218 219@node gettext Invocation 220@subsubsection Invoking the @code{gettext} program 221 222@include rt-gettext.texi 223 224Note: @code{xgettext} supports only the one-argument form of the 225@code{gettext} invocation, where no options are present and the 226@var{textdomain} is implicit, from the environment. 227 228@node ngettext Invocation 229@subsubsection Invoking the @code{ngettext} program 230 231@include rt-ngettext.texi 232 233Note: @code{xgettext} supports only the three-arguments form of the 234@code{ngettext} invocation, where no options are present and the 235@var{textdomain} is implicit, from the environment. 236 237@node envsubst Invocation 238@subsubsection Invoking the @code{envsubst} program 239 240@include rt-envsubst.texi 241 242@node eval_gettext Invocation 243@subsubsection Invoking the @code{eval_gettext} function 244 245@cindex @code{eval_gettext} function, usage 246@example 247eval_gettext @var{msgid} 248@end example 249 250@cindex lookup message translation 251This function outputs the native language translation of a textual message, 252performing dollar-substitution on the result. Note that only shell variables 253mentioned in @var{msgid} will be dollar-substituted in the result. 254 255@node eval_ngettext Invocation 256@subsubsection Invoking the @code{eval_ngettext} function 257 258@cindex @code{eval_ngettext} function, usage 259@example 260eval_ngettext @var{msgid} @var{msgid-plural} @var{count} 261@end example 262 263@cindex lookup plural message translation 264This function outputs the native language translation of a textual message 265whose grammatical form depends on a number, performing dollar-substitution 266on the result. Note that only shell variables mentioned in @var{msgid} or 267@var{msgid-plural} will be dollar-substituted in the result. 268 269@node eval_pgettext Invocation 270@subsubsection Invoking the @code{eval_pgettext} function 271 272@cindex @code{eval_pgettext} function, usage 273@example 274eval_pgettext @var{msgctxt} @var{msgid} 275@end example 276 277@cindex lookup message translation with context 278This function outputs the native language translation of a textual message 279in the given context @var{msgctxt} (see @ref{Contexts}), performing 280dollar-substitution on the result. Note that only shell variables mentioned 281in @var{msgid} will be dollar-substituted in the result. 282 283@node eval_npgettext Invocation 284@subsubsection Invoking the @code{eval_npgettext} function 285 286@cindex @code{eval_npgettext} function, usage 287@example 288eval_npgettext @var{msgctxt} @var{msgid} @var{msgid-plural} @var{count} 289@end example 290 291@cindex lookup plural message translation with context 292This function outputs the native language translation of a textual message 293whose grammatical form depends on a number in the given context @var{msgctxt} 294(see @ref{Contexts}), performing dollar-substitution on the result. Note 295that only shell variables mentioned in @var{msgid} or @var{msgid-plural} 296will be dollar-substituted in the result. 297