использование кавычек с tr в Linux - PullRequest
0 голосов
/ 05 июля 2018

Я наткнулся на странную ошибку в bash-скрипте. Скрипт меняет ввод пользователя на строчные. Как следующее:

# echo AcCCept | tr [:upper:] [:lower:]

Я решил добавить кавычки (или двойные кавычки). Странно то, что точно такая же команда, которая не работала в system-a, отлично работала в system-b. система-а имеет Centos7.5. Система-б имеет Centos7.4. Тем не менее, версии bash & tr одинаковы для обоих.

Вывод из системы-а с проблемой:

[root@system-a ~]# echo AcCCept | tr [:upper:] [:lower:]
tr: misaligned [:upper:] and/or [:lower:] construct
[root@system-a ~]#
[root@system-a ~]#
[root@system-a ~]# echo AcCCept | tr [:upper:] [:lower:]
tr: misaligned [:upper:] and/or [:lower:] construct
[root@system-a ~]# echo AcCCept | tr "[:upper:]" "[:lower:]"
acccept
[root@system-a ~]# bash -version
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
<http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
[root@system-a ~]# tr --version
tr (GNU coreutils) 8.22
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Jim Meyering.
[root@system-a ~]# cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)
[root@system-a ~]#

Вывод из system-b - работает нормально:

echo AcCCept | tr [:upper:] [:lower:]
acccept
[root@system-b ~]# echo AcCCept | tr "[:upper:]" "[:lower:]"
acccept
[root@system-b ~]# bash -version
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
[root@system-b ~]# tr --version
tr (GNU coreutils) 8.22
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Jim Meyering.
[root@system-b ~]# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
[root@system-b ~]# 

В чем причина того, что та же команда не выполнена в system-a и нормально работает в system-b?

1 Ответ

0 голосов
/ 05 июля 2018

Если без кавычек, [...] подлежит расширению пути . Например, если у вас в каталоге есть файл с именем u, то [:upper:] расширится до него:

$ ls                     # dir is empty
$ echo [:upper:]         # [:upper:] doesn't expand to anything and gets printed as is
[:upper:]
$ touch u                # filename 'u' created
$ echo [:upper:]         # [:upper:] expands to 'u'
u
$ echo '[:upper:]'       # [:upper:] is protected by quotes and doesn't get expanded 
[:upper:]

Почему это проблема? Цитата из man tr:

tr [OPTION]... SET1 [SET2]

Только [:lower:] и [:upper:] гарантированно расширяются в порядке возрастания; используется в SET2 при переводе, они могут использоваться только парами для указания преобразование регистра.

Это означает, что если вы используете [:lower:] в SET2, [:upper:] или [:lower:] должны использоваться в SET1. В противном случае вы получите ошибку:

$ tr '[:upper:]' '[:lower:]' <<< "TeXt"      # SET1: [:upper:] SET2: [:lower:] => OK 
text
$ tr 'u' '[:lower:]' <<< "TeXt"              # SET2: [:lower:] SET1: not [:upper:] => ERROR      
tr: misaligned [:upper:] and/or [:lower:] construct 
$ tr '[:upper:]' 'l' <<< "TeXt"              # SET1: [:upper:] SET2: l => OK             
lelt
...