Копирайт на команду /bin/true

Автор оригинала: John Chambers
  • Перевод
Среди всей этой шумихи по поводу авторских прав есть один забавный пример — это крайний случай использования копирайта, который породила AT&T где-то в 1980-х. Речь идёт о программе /bin/true. Это пустая программа, которую обычно используют только для того, чтобы писать бесконечные циклы (while true do ...) в шелл-скриптах. Программа «true» не делает ничего, а только завершается с нулевым кодом. Такого поведения легко добиться — достаточно просто создать пустой файл и сделать его исполняемым, что и делали создатели первых Unix-систем. Пустой файл интерпретируется как шелл-скрипт, который не делает ровным счётом ничего. А, поскольку у него это вполне успешно получается, шелл возвращает нулевой код завершения. Но юристы AT&T решили, что это не помешает защитить копирайтом.

Самая старая версия /bin/true с копирайтом, которую я нашёл, относится к 1984-ому:

 #     Copyright (c) 1984 AT&T
 #       All Rights Reserved
 
 #     THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T
 #     The copyright notice above does not evidence any
 #     actual or intended publication of such source code.
 
 #ident        "@(#)cmd/true.sh        50.1"

И это весь файл. Заметьте, здесь всего три пустые строки и комментарий (строчка с #ident указывает, что это за программа). Да, вы правильно поняли; у AT&T есть копирайт на три пустые строки. Так что, если в каких-то ваших файлах есть пустые строки, вы нагло нарушаете копирайт AT&T.

Чтобы вы не подумали, что это просто случайность, которую быстро исправили, посмотрите на программу /bin/true из Sys/V, которую AT&T выпустила в 1989:

 #     Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
 #       All Rights Reserved
 
 #     THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T
 #     The copyright notice above does not evidence any
 #     actual or intended publication of such source code.
 
 #ident  "@(#)true.sh    1.6     93/01/11 SMI"   /* SVr4.0 1.4   */

Как видите, здесь по-прежнему нет ничего, кроме трёх пустых строк и сообщения о копирайте. Ах, ещё строчка с #indent нам сообщает, что версия этой программы теперь 1.6.

Кстати, раз я «публикую» целую программу AT&T, я бесстыдно нарушаю их копирайт. Я неоднократно публично указывал на это на разных технических форумах, начиная с 1980-х. До сих пор юристы из AT&T ко мне не обращались. Кто-нибудь в курсе, почему они игнорируют такое вопиющее нарушение?

В linux такого нарушения нет, потому что там используют скомпилированную версию /bin/true. К слову, она работает гораздо быстрее, чем упомянутый шелл-скрипт, потому что не запускает лишнюю программу (/bin/sh) только ради того, чтобы она сразу же завершилась. Вот она, причина, по которой linux работает быстрее unix. И это улучшение неизбежно пришлось сделать, чтобы не нарушить копирайт AT&T ;-)

Дополнение

AT&T — не единственная компания, которая делает такое. Вот та же программа из Solaris, 1993:

 $ cat /usr/bin/true
 #!/usr/bin/sh
 #       Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
 #         All Rights Reserved
 
 #       THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T
 #       The copyright notice above does not evidence any
 #       actual or intended publication of such source code.
 
 #ident  "@(#)true.sh    1.6     93/01/11 SMI"   /* SVr4.0 1.4   */

Обратите внимание, здесь на одну пустую строку меньше; её заменили на "#!/usr/bin/sh". В остальном программы идентичны. Sun просто оставили тот же самый комментарий. Интересно, а Sun получила от AT&T письменное разрешение использовать эти пустые строки? И ещё меня немного смущает, что Sun даже не заменили «AT&T» на «Sun Microsystems». Может, их юристы решили, что не стоит этого делать?

А ребята и GNU обошли эту проблему, заново реализовав команду «true» на C. Эта программа не только меньше и быстрее, чем старый скрипт, которому надо запустить целый новый процесс, чтобы успешно ничего не сделать. Они также добавили важные опции:

   --help      display this help and exit
   --version   output version information and exit

Возможно, они добавили эти опции, чтобы нельзя было сказать, что они просто украли код у AT&T; ведь версия от GNU хоть что-то делает. Похоже, у ребят из GNU есть чувство юмора. Ниже я скопировал сообщение от «true --version» в knoppix в 2007-ом. Заметьте, это уже версия 5.94. Тут говорится, что на программу не предоставляется никакой гарантии. По-видимому, это значит, что если программа, вопреки своему предназначению, что-то делает, то вы не можете засудить автора. А ещё эта версия делает кое-что уж совсем «необычное»: она сообщает нам имя своего автора.

 $ /bin/true --version
 true (GNU coreutils) 5.94
 Copyright (C) 2006 Free Software Foundation, Inc.
 This is free software.  You may redistribute copies of it under the terms of
 the GNU General Public License .
 There is NO WARRANTY, to the extent permitted by law.
 
 Written by Jim Meyering.
 $

Команда /bin/true (или /usr/bin/true) сегодня практически не используется, так как большинство шеллов просто заменяют её встроенной командой. Но иногда она всё-таки бывает нужна по разным причинам, и попытки объявить на неё копирайт всё ещё служат хорошим поводом для шуточек. Особенно забавно, что у GNU есть причины указывать копирайт для их версии. Благодаря этому AT&T, Sun или SCO не могут взять код GNU, сказать что он их собственный, а потом засудить линуксоидов якобы за нарушение.
Поделиться публикацией

Комментарии 62

  • НЛО прилетело и опубликовало эту надпись здесь
      +1
      А у меня true --help и true --version не работают, хоть и в мане есть :(

      Жаль, что «man true» не может ответить на все вопросы жизни
        +18
        Use /bin/true luke.
          +2
          да, так заработало
          0
          Попробуйте "/bin/true --help". Вероятно, шелл использует свою встроенную команду.
            +4
            По идее, на все вопросы жизни должен уметь ответить скорее «true man» :)
              +1
              [user@fegore ~]$ true man
              [user@fegore ~]$ 
              

              :(
                +6
                Не так.

                > if true man; then echo True Man;fi
                True Man
            +24
            man false:
            false — do nothing, unsuccessfully
              +2
              все потому что

              man true:
              true — do nothing, successfully
                0
                Программам тоже свойственнен фатализм. Или пессимизм?
                  0
                  Report false bugs to bug-coreutils@gnu.org
                • НЛО прилетело и опубликовало эту надпись здесь
                    +75
                    0.1 Alpha version
                    0.2 Beta version
                    0.5 Added empty string
                    0.8 Added empty string
                    1.0 Final version with core v.1
                    1.1 Bug fix, added an empty string

                    Future:
                    2.0.Beta. Rewrite the core. Added two empty lines
                      +12
                      А тем временем версия уже 8.16! Целых 7 мажорных обновлений было)
                      (Проверял на Arch Linux если что)
                      • НЛО прилетело и опубликовало эту надпись здесь
                        • НЛО прилетело и опубликовало эту надпись здесь
                            +10
                            А я сижу залипаю и поверил вам, так же не подумав и полез искать обновления для неё.
                            Вдруг и правда ТАКАЯ дыра в системе.
                            Ну лан, зато всё остальное обновил)
                              0
                              Нет, чтобы назвать их «8.05» и «8.16».
                              А потом удивляемся школьникам младших классов на торрент-трекерах, доказывающих, что их рейтинг «0.11» уж всяко больше «0.9».
                                +3
                                просто версия — это, как правило, строка, а не дробное число.
                              0
                              # /bin/true --version
                              true (GNU coreutils) 8.16
                              Упакован Gentoo (8.16 (p1))
                              Copyright (C) 2012 Free Software Foundation, Inc.
                              Лицензия GPLv3+: GNU GPL версии 3 или новее <http://gnu.org/licenses/gpl.html>
                              Это свободное ПО: вы можете продавать и распространять его.
                              Нет НИКАКИХ ГАРАНТИЙ до степени, разрешённой законом.
                              
                              Автор программы -- Jim Meyering.
                              
                              
                                +1
                                /bin/true --version
                                true (GNU coreutils) 8.17

                                :p
                              +2
                              Обновите Arch! Сейчас актуальна 8.17 =)
                                0
                                Да я обновил, только вот теперь FreeNX ом криво цепляюсь) Зато версия true теперь труЪ
                                0
                                coreutils регулярно обновляются… Чтоб федоровцам жизнь мёдом не казалась ,)
                                  0
                                  На Ubuntu 12.04 у меня версия 8.13 =(
                                  Дайте ссылку на репозиторий, я хоть из исходников скомпилю и поставлю :)
                                  +6
                                  а вот история развития и эволюции GNUтой true вплоть до января 2012:
                                  git.savannah.gnu.org/gitweb/?p=coreutils.git;a=history;f=src/true.c;h=b37ac543c983ae8e536c1478536af625bf2602f9;hb=v8.17
                                  +23
                                  Получается, что когда кто-нибудь начинает писать новый скрипт, он просто меняет true AT&T?
                                    +2
                                    Нет иной истины, кроме Б-гоподобного true и детей его. Админь.
                                    +63
                                    Все, кто шутил по поводу копирайта на "int i;" в прошлых топиках — просто лузеры в сравнении с AT&T.
                                      +9
                                      > Возможно, они добавили эти опции, чтобы нельзя было сказать, что они просто украли код у AT&T

                                      Наверно причина всё-таки в том, чтобы удовлетворить GNU-стилю опций для консольных команд (длинные опции начинаются с двух минусов, однобуквенные — с одной, обязательно наличие --help и --version).

                                      Если же в этой фразе была шутка автора поста, то она тонка и зачетна. ;)
                                        +18
                                        Также улыбнуло следующее при /bin/true --help
                                        Report true bugs to bug-coreutils@gnu.org

                                          +1
                                          где скачать последнюю версию для Windows?
                                            +51
                                            4.7Gb весом, с таблэткой
                                              +3
                                              Если надо именно скачать, и именно последнюю версию, то:
                                              sourceware.org/pub/cygwin/release/coreutils/coreutils-8.10-1.tar.bz2
                                              В архиве в папке /usr/bin
                                              Она не заработает без установленного cygwin либо без cygwin1.dll, скопированного в её папку.
                                              Она поддерживаться будет долго. Есть ещё один вариант.
                                                +2
                                                Есть ещё вариант, но он объявлен как deprecated в windows 8.
                                                Скачать www.microsoft.com/en-us/download/details.aspx?id=2391
                                                распаковать (это SFX-ZIP архив, открывается архиваторами), в BaseUtils/bin лежит искомый файл.
                                                  +17
                                                  Думаю Вам подойдет такой вариант, самый свежий ;) Сохранить как true.bat
                                                  @echo off
                                                  rem     Copyright (c) 1984 AT&T
                                                  rem       All Rights Reserved
                                                   
                                                  rem     THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T
                                                  rem     The copyright notice above does not evidence any
                                                  rem     actual or intended publication of such source code.
                                                   
                                                  rem ident        "@(#)cmd/true.sh        50.1"
                                                  
                                                    +21
                                                    Это самое наглое нарушение копирайта AT&T — портировать их детище на Windows)))
                                                      +8
                                                      В вашем варианте есть undefined behavior, что есть потенциальная уязвимость. Пропатчил:

                                                      @echo off
                                                      rem Copyright (c) 1984 AT&T
                                                      rem All Rights Reserved

                                                      rem THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T
                                                      rem The copyright notice above does not evidence any
                                                      rem actual or intended publication of such source code.
                                                      rem
                                                      rem Authors: DmZ@habrahabr.ru, amc@habrahabr.ru
                                                      rem Report bugs to: habrahabr.ru/post/144058/#comment_4832831

                                                      SET ERRORLEVEL=0

                                                      rem ident "@(#)cmd/true.sh 50.1"
                                                        +3
                                                        В вашем варианте не видно, что это ваш вариант.
                                                        -rem ident "@(#)cmd/true.sh 50.1"
                                                        +rem ident "@(#)cmd/true.sh 51.1"
                                                        
                                                        Changelog:
                                                        Completelty rewrited, removed undefined behavior
                                                    +14
                                                    С false ситуация ещё интересней. Как следует из названия, программа false всегда возвращает false и используется обычно для подавления успешного возврата и приостановки.
                                                    make sandwich && false && rm -rf / # make научился делать сэндвичи, зачем удаляться?
                                                    

                                                    Так вот, если программу false удалить, попытка её вызова будет приводить всё к той же неудаче и остановке! Получается, у AT&T есть копирайт и на отсутствие программы как таковой?
                                                      0
                                                      варианта два — шелл илпользует встроенную команду либо шелл пытается вызвать несуществующую команду и обламывается
                                                      +7
                                                      А может просто их билд-сервер помечает комментариями с копирайтом все скрипты?
                                                        0
                                                        честно говоря сомневаюсь, что в 80-ые года были вообще билд-сервера :)
                                                          +10
                                                          Были.
                                                            +8
                                                            Как-раз напротив, их было куда больше.
                                                          +3
                                                          /usr/bin/clear из Solaris:

                                                          #ident "@(#)clear.sh 1.8 96/10/14 SMI" /* SVr4.0 1.3 */
                                                          # Copyright (c) 1987, 1988 Microsoft Corporation
                                                          # All Rights Reserved

                                                          # This Module contains Proprietary Information of Microsoft
                                                          # Corporation and should be treated as Confidential.

                                                          # clear the screen with terminfo.
                                                          # if an argument is given, print the clear string for that tty type

                                                          /usr/bin/tput ${1:+-T$1} clear 2> /dev/null
                                                          exit

                                                          Думаю за мной уже выехали.
                                                            +59
                                                            Выше дали ссылку на историю развития GNU true, и должен признать, что это весьма увлекательное чтиво:
                                                             

                                                            Рождение
                                                            --- /dev/null
                                                            +++ b/src/true.c
                                                            @@ -0,0 +1,5 @@
                                                            +int
                                                            +main ()
                                                            +{
                                                            +  exit (0);
                                                            +}
                                                            


                                                            Развитие до полноценного приложения энтерпрайз-уровня (сообщайте о багах!)
                                                            +#include <config.h>
                                                            +#include <stdio.h>
                                                            +#include <sys/types.h>
                                                            +#include "system.h"
                                                            +#include "version-etc.h"
                                                            +
                                                            +#define PROGRAM_NAME "true"
                                                            +#define AUTHORS "no one"
                                                            ...
                                                            +Usage: %s\n\
                                                            +  or:  %s OPTION\n\
                                                            +Exit with a status code indicating success.\n\
                                                            +These option names may not be abbreviated.
                                                            +\n\
                                                            +  --help      display this help and exit\n\
                                                            +  --version   output version information and exit\n\
                                                            +")
                                                            +         , program_name, program_name);
                                                            +  puts (_("\nReport bugs to <bug-sh-utils@gnu.org>."));
                                                            +  exit (status);
                                                            +}
                                                            ...
                                                            


                                                            Обрастание стандартной шапкой GPL и упоминание конкретного автора
                                                            +   This program is free software; you can redistribute it and/or modify
                                                            +   it under the terms of the GNU General Public License as published by
                                                            +   the Free Software Foundation; either version 2, or (at your option)
                                                            +   any later version.
                                                            ...
                                                            
                                                            -#define AUTHORS "no one"
                                                            +#define AUTHORS "Jim Meyering"
                                                            


                                                            Программа была недостаточно общей — теперь есть false версия
                                                            -#define PROGRAM_NAME "true"
                                                            +/* Act like "true" by default; false.c overrides this.  */
                                                            +#ifndef EXIT_STATUS
                                                            +# define EXIT_STATUS EXIT_SUCCESS
                                                            +#endif
                                                            +
                                                            +#if EXIT_STATUS == EXIT_SUCCESS
                                                            +# define PROGRAM_NAME "true"
                                                            +#else
                                                            +# define PROGRAM_NAME "false"
                                                            +#endif
                                                            ...
                                                            
                                                            -  exit (EXIT_SUCCESS);
                                                            +  exit (EXIT_STATUS);
                                                            


                                                            Включение в общий багрепортинг
                                                            -  printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
                                                            +  emit_bug_reporting_address ();
                                                            


                                                            Локализация подоспела
                                                            -           ? "Exit with a status code indicating success."
                                                            -           : "Exit with a status code indicating failure."));
                                                            +           ? N_("Exit with a status code indicating success.")
                                                            +           : N_("Exit with a status code indicating failure.")));
                                                            


                                                            Security update (найдена уязвимость!)
                                                            * src/true.c (main): There is no reason to examine argv[0],
                                                             call atexit, etc., in the usual case in which we're about to exit.
                                                             This has the side effect of making it so that these programs
                                                             no longer segfault when subjected to execve abuse.
                                                             Before this change, these commands would make "true" segfault:
                                                               printf '%s\n' '#include <unistd.h>' 'int main(int c, char**v)' \
                                                                 '{ execve (v[1], 0, 0); }' > k.c && gcc k.c && ./a.out $PWD/true
                                                             Now it succeeds.  Reported by Tetsuo Handa and Bart Van Assche
                                                             via Ondřej Vašík in http://bugzilla.redhat.com/537684.
                                                            

                                                            --- a/src/true.c
                                                            +++ b/src/true.c
                                                            @@ -54,18 +54,18 @@
                                                             int
                                                             main (int argc, char **argv)
                                                             {
                                                            -  initialize_main (&argc, &argv);
                                                            -  set_program_name (argv[0]);
                                                            -  setlocale (LC_ALL, "");
                                                            -  bindtextdomain (PACKAGE, LOCALEDIR);
                                                            -  textdomain (PACKAGE);
                                                            -
                                                            -  atexit (close_stdout);
                                                            -
                                                               /* Recognize --help or --version only if it's the only command-line
                                                                  argument.  */
                                                               if (argc == 2)
                                                                 {
                                                            +      initialize_main (&argc, &argv);
                                                            +      set_program_name (argv[0]);
                                                            +      setlocale (LC_ALL, "");
                                                            +      bindtextdomain (PACKAGE, LOCALEDIR);
                                                            +      textdomain (PACKAGE);
                                                            +
                                                            +      atexit (close_stdout);
                                                            +
                                                            


                                                            Там ещё десятки коммитов, но в основном просто версия в тексте меняется.
                                                              0
                                                              Интересно, сколько ресурсов потребляет такая команда при запуске? Уж не подвесит ли систему?)))
                                                                +1
                                                                Маразм крепчал :)
                                                                  +10
                                                                  Не забывайте что Oracle закопирайтила Hello world на джаве docs.oracle.com/javase/tutorial/getStarted/application/examples/HelloWorldApp.java
                                                                    0
                                                                    Ради интереса посмотрел на своем маке:
                                                                    mate /usr/bin/true
                                                                    

                                                                    Это бинарный файл, в котором встречаются следующие строки:
                                                                    Apple Inc.
                                                                    Apple Certification Authority
                                                                    Apple Code Signing Certification Authority
                                                                    Apple Root

                                                                    то есть тут тоже не обошлось без копирайта на столь полезную программу =)
                                                                      0
                                                                      это цифровая подпись.
                                                                        +1
                                                                        Корни другие:

                                                                        TRUE(1)                   BSD General Commands Manual                  TRUE(1)
                                                                        
                                                                        NAME
                                                                             true -- Return true value.
                                                                        
                                                                        SYNOPSIS
                                                                             true
                                                                        
                                                                        DESCRIPTION
                                                                             The true utility always returns with exit code zero.
                                                                        
                                                                        SEE ALSO
                                                                             csh(1), sh(1), false(1)
                                                                        
                                                                        STANDARDS
                                                                             The true utility conforms to IEEE Std 1003.2-1992 (``POSIX.2'').
                                                                        
                                                                        BSD                              June 27, 1991                             BSD
                                                                        (END) 
                                                                        
                                                                        +1
                                                                        www.gnu.org/software/hello/ даже с документацией и рассылкой.
                                                                          0
                                                                          В андроиде true бинарный, по его размеру я бы не сказал, что это 6 строк кода
                                                                            +1
                                                                            > Кто-нибудь в курсе, почему они игнорируют такое вопиющее нарушение?

                                                                            Думаю, ждут, чтобы собрать побольше случаев использования и махом предъявить Вам счет на кр-у-у-гленькую сумму.

                                                                            Будем надеяться, что в Вашем случае тоже попадется судья, умеющие программировать :)
                                                                              0
                                                                              Они ждут, пока не будет нарушен копирайт на 9 строк кода, по сегодняшним меркам 3 — маловато будет :)
                                                                              0
                                                                              true (GNU coreutils) 8.13
                                                                              Copyright © 2011 Free Software Foundation, Inc.
                                                                              Лицензия GPLv3+: GNU GPL версии 3 или новее <gnu.org/licenses/gpl.html>

                                                                              Ubuntu 12.04 =)
                                                                                0
                                                                                Им пора переходить на новый 6-недельный цикл.
                                                                                  0
                                                                                  Угу, как mozilla с огнелисом =)
                                                                                +5
                                                                                Автор на самом деле либо извращенно иронизирует и можно это расценивать как пятничный стёб либо он полный лох (я про автора, не переводчика).
                                                                                1) --help и --version — это стандарт GNUшных утилит.

                                                                                2) Компания Sun (и любая другая) не имела права менять копирайт в чужом коде. Изменение копирайта в заимствованном файле есть нарушение закона. А шебанг скорее всего появился по какой-то причине, например команда на солярке без него не запускалась.

                                                                                3) История появления. Смотрим последнюю строку, которая имеет некий шаблонный вид (та, что с #indent начинается).
                                                                                Теперь смотрим в сырцы java, например в файл com/sun/javadoc/Doc.java (у меня версия под рукой 1.6.29). Там видим такую строку * @(#)Doc.java 1.15 02/09/29
                                                                                Похоже? И я знаю почему — это битый SCCS кейворд. Если вы посмотрите в другие сырцы, там будет написано %W% %E% — это нормальные SCCS кейворды, которые и должны раскрываться в имя файла, дату и версию итд. Но сейчас джава уже не живет под SCCS, поэтому мы видим нераскрытые макросы в большинстве исходников.
                                                                                Вывод — пустой файл хранился под версионкой в SCCS и туда автоматом добавили кейворды как и во все остальные файлы.

                                                                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                                Самое читаемое