5

I have a program here, that depends on the output of netstat. More concrete: netstat -apn.

Here is an example of a normal output.

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -

A client of mine has some other output (as an example):

Proto Recv-Q Send-Q Endereço Local          Endereço Remoto         Estado      PID/Program name
tcp        0      0 0.0.0.0:111             0.0.0.0:*               OUÇA       -

I want to test my software with a changed output of netstat, like the output of the client.

So the question is: What should I do to change the output language of netstat, so I can reproduce the errors, the client gets?

I already tried to change the language with export LANG=pt_PT, but the output didn't change.

  • What operating system are you using? If Linux, which one? – terdon Oct 14 '15 at 9:10
  • @terdon Operating System is Debian. – kristian Oct 14 '15 at 10:41
  • Ah, cool, then my answer should be relevant. Could you get it to work with Portuguese though? I couldn't get netstat to work, only other commands. – terdon Oct 14 '15 at 10:42
  • @terdon Yes it worked. Big thanks to you! – kristian Oct 14 '15 at 11:02
  • Really? Are you sure that's Debian and not Ubuntu? – terdon Oct 14 '15 at 11:03
6

First you need to make sure that your machine has the necessary locale set up. You can see available locales with locale -a. For example, on my system:

$ locale -a
C
C.UTF-8
el_GR.utf8
en_US.utf8
fr_FR.utf8
POSIX

As you can see above, I don't have the Portuguese locale. On my Debian, I can create it by running sudo dpkg-reconfigure locales, and choosing the relevant locale:

Package configuration

 ┌──────────────────────────┤ Configuring locales ├──────────────────────────┐  
 │ Locales are a framework to switch between multiple languages and allow    │  
 │ users to use their language, country, characters, collation order, etc.   │  
 │                                                                           │  
 │ Please choose which locales to generate. UTF-8 locales should be chosen   │  
 │ by default, particularly for new installations. Other character sets may  │  
 │ be useful for backwards compatibility with older systems and software.    │  
 │                                                                           │  
 │ Locales to be generated:                                                  │  
 │                                                                           │  
 │    [ ] pt_BR.UTF-8 UTF-8                                              ↑   │  
 │    [ ] pt_PT ISO-8859-1                                               ▒   │  
 │    [*] pt_PT.UTF-8 UTF-8                                              ▮   │  
 │    [ ] pt_PT@euro ISO-8859-15                                         ▒   │  
 │    [ ] quz_PE UTF-8                                                   ↓   │  
 │                                                                           │  
 │                                                                           │  
 │                    <Ok>                        <Cancel>                   │  
 │                                                                           │  
 └───────────────────────────────────────────────────────────────────────────┘  

After hitting Enter, you should get:

$ sudo dpkg-reconfigure locales
Generating locales (this might take a while)...
  el_GR.UTF-8... done
  en_US.UTF-8... done
  fr_FR.UTF-8... done
  pt_PT.UTF-8... done
Generation complete.

If you are not using a Debian-based distribution, you will need to do this manually:

  1. Add the relevant locale name to /etc/locale.gen. For example:

    pt_PT.UTF-8 UTF-8
    
  2. Run locale-gen

After the above steps (either the manual approach or the dpkg-reconfigre locales one), locale -a will also list the Portuguese locale:

$ locale -a
C
C.UTF-8
el_GR.utf8
en_US.utf8
fr_FR.utf8
POSIX
pt_PT.utf8

Now, you can choose what language output is displayed in:

$ LC_ALL=el_GR.utf8 date
Τετ 14 Οκτ 2015 12:34:28 μμ EEST
$ LC_ALL=fr_FR.utf8 date
mercredi 14 octobre 2015, 12:35:07 (UTC+0300)
$ LC_ALL=pt_PT.utf8 date
Qua Out 14 12:35:11 EEST 2015

However, whether or not a particular program is capable of printing output in the selected locale will depend on whether it has been translated; on whether the package ships with the relevant .mo translation file. In the case of netstat, this is /usr/share/locale/${LANG%_*}/LC_MESSAGES/net-tools.mo. On my Debian, the French locale has it but the Portuguese one does not:

$ ls /usr/share/locale/{fr,pt}/LC_MESSAGES/net*
ls: cannot access /usr/share/locale/pt/LC_MESSAGES/net*: No such file or directory
/usr/share/locale/fr/LC_MESSAGES/net-tools.mo

This is why I can run netstat in French:

$ LC_ALL=fr_FR.utf8 netstat -apn | head -n2
(Tous les processus ne peuvent être identifiés, les infos sur les processus
non possédés ne seront pas affichées, vous devez être root pour les voir toutes.)
Connexions Internet actives (serveurs et établies)
Proto Recv-Q Send-Q Adresse locale          Adresse distante        Etat        PID/Program name

But not in Portuguese:

$ LC_ALL=pt_PT.utf8 netstat -apn | head -n2
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
4

You need to install language pack for the language you chose, otherwise the text translation utility (gettext on GNU systems) can not translate the messages to your chosen language:

$ strace -fe trace=open sh -c 'LANGUAGE=fr_FR.utf8 netstat -tnlp'
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
Process 14847 attached
[pid 14847] open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
[pid 14847] open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
[pid 14847] open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
[pid 14847] open("/proc/3690/cmdline", O_RDONLY) = 5
[pid 14847] open("/proc/8579/cmdline", O_RDONLY) = 5
[pid 14847] open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
[pid 14847] open("/usr/share/locale/fr_FR.utf8/LC_MESSAGES/net-tools.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 14847] open("/usr/share/locale/fr_FR/LC_MESSAGES/net-tools.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 14847] open("/usr/share/locale/fr.utf8/LC_MESSAGES/net-tools.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 14847] open("/usr/share/locale/fr/LC_MESSAGES/net-tools.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 14847] open("/usr/share/locale-langpack/fr_FR.utf8/LC_MESSAGES/net-tools.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 14847] open("/usr/share/locale-langpack/fr_FR/LC_MESSAGES/net-tools.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 14847] open("/usr/share/locale-langpack/fr.utf8/LC_MESSAGES/net-tools.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 14847] open("/usr/share/locale-langpack/fr/LC_MESSAGES/net-tools.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
....
[pid 14847] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=14847, si_status=0, si_utime=0, si_stime=2} ---
+++ exited with 0 +++

You can see the process try to look in /usr/share/locale and /usr/share/locale-langpack to get the translate text for net-tools package (which netstat belong to).

Now, install the language pack made it work. On Ubuntu system:

sudo apt-get install language-pack-fr

Other system, the relevant language pack for package can be include by the package itself, at least on Debian and Centos:

$ apt-file search /usr/share/locale/fr/LC_MESSAGES/net-tools.mo
net-tools: /usr/share/locale/fr/LC_MESSAGES/net-tools.mo

(On Centos you can use yum whatprovides)

Then:

$ strace -fe trace=open sh -c 'LANGUAGE=fr_FR.utf8 netstat -tnlp'
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
Process 15155 attached
[pid 15155] open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
[pid 15155] open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
[pid 15155] open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
[pid 15155] open("/proc/3690/cmdline", O_RDONLY) = 5
[pid 15155] open("/proc/8579/cmdline", O_RDONLY) = 5
[pid 15155] open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
[pid 15155] open("/usr/share/locale/fr_FR.utf8/LC_MESSAGES/net-tools.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 15155] open("/usr/share/locale/fr_FR/LC_MESSAGES/net-tools.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 15155] open("/usr/share/locale/fr.utf8/LC_MESSAGES/net-tools.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 15155] open("/usr/share/locale/fr/LC_MESSAGES/net-tools.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 15155] open("/usr/share/locale-langpack/fr_FR.utf8/LC_MESSAGES/net-tools.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 15155] open("/usr/share/locale-langpack/fr_FR/LC_MESSAGES/net-tools.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 15155] open("/usr/share/locale-langpack/fr.utf8/LC_MESSAGES/net-tools.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 15155] open("/usr/share/locale-langpack/fr/LC_MESSAGES/net-tools.mo", O_RDONLY) = 3
[pid 15155] open("/usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache", O_RDONLY) = 3
(Tous les processus ne peuvent être identifiés, les infos sur les processus
non possédés ne seront pas affichées, vous devez être root pour les voir toutes.)
Connexions Internet actives (seulement serveurs)
Proto Recv-Q Send-Q Adresse locale          Adresse distante        Etat       PID/Program name
....
[pid 15155] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=15155, si_status=0, si_utime=0, si_stime=3} ---
+++ exited with 0 +++

/usr/share/locale-langpack/fr/LC_MESSAGES/net-tools.mo existed, gettext() successfully to translate the messages.

Note that not all words can be translated, my hometown vi_VN locale didn't work even if I installed the language-pack-vi.


You should use LC_ALL to override all other localisation settings, except LANGUAGE in GNU system as above.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.