Удар распознает объявление переменной как строку, если Вы не помещаете кавычки?

На хинду, что первый символ в файле Linux полномочия drwxrwxrwx средства:

Первый символ дает Вам подсказку типа объекта, который это.

Возможные значения для того первого символа: ( -, d, c, l, p, s, b, D )

- (тире) означает файл и и d означает каталог.

el@angeliqe ~/tmpdir $ mkdir my_empty_directory
el@angeliqe ~/tmpdir $ touch myfile.txt
el@angeliqe ~/tmpdir $ ls -al
total 16
drwxrwxr-x 3 el users 4096 Dec 21 13:06 .
drwx--x--x 9 el users 4096 Dec 21 11:47 ..
drwxrwxr-x 3 el users 4096 Dec 21 11:54 my_empty_directory
-rw-rw-r-- 1 el users  182 Dec 21 11:45 myfile.txt

my_empty_directory имеет 'd' и каталог, и myfile.txt имеет '-' и файл обычного текста.

c означает файл устройства посимвольного ввода-вывода

el@angeliqe /dev $ ls -al
total 4
drwxr-xr-x 12 root root      4080 Dec 19 21:18 .
drwxr-xr-x 20 root root      4096 Nov  3 19:00 ..
crw-rw----  1 root tty     7, 133 Nov 24 10:13 vcsa5

vcsa5 является файлом устройства посимвольного ввода-вывода. Найдите файлы устройства посимвольного ввода-вывода с этой командой: find / -type c -print 2>/dev/null

b означает блочное устройство

el@angeliqe /dev $ ls -al
total 4
drwxr-xr-x 12 root root      4080 Dec 19 21:18 .
drwxr-xr-x 20 root root      4096 Nov  3 19:00 ..
brw-rw----  1 root disk    8,   0 Nov 24 10:13 sda

sda является блочным устройством. Найдите файлы блочного устройства с этой командой: find / -type b -print 2>/dev/null

l означает ссылку

el@angeliqe ~/tmpdir $ touch myfile.txt
el@angeliqe ~/tmpdir $ ln -s myfile.txt myfile2.txt
el@angeliqe ~/tmpdir $ ls -al
total 8
drwxrwxr-x 2 el users 4096 Dec 21 13:23 .
drwx--x--x 9 el users 4096 Dec 21 13:22 ..
-rw-rw-r-- 1 el users    0 Dec 21 13:23 myfile.txt
lrwxrwxrwx 1 el users   10 Dec 21 13:23 myfile2.txt -> myfile.txt

myfile2.txt символьная ссылка на myfile.txt. Найдите файлы символьной ссылки с этой командой: find / -type l -print 2>/dev/null

p означает именованный канал

el@angeliqe /dev $ ls -al
total 4
drwxr-xr-x 12 root root      4080 Dec 19 21:18 .
drwxr-xr-x 20 root root      4096 Nov  3 19:00 ..
prw-------  1 root root         0 Nov 24 10:13 initctl

initctl является именованным каналом. Найдите файлы канала с этой командой: find / -type p -print 2>/dev/null

s является сокетом

el@angeliqe /dev $ ls -al
total 4
drwxr-xr-x 12 root root      4080 Dec 19 21:18 .
drwxr-xr-x 20 root root      4096 Nov  3 19:00 ..
srwxrwxrwx  1 root root         0 Nov 24 10:13 gpmctl

gpmctl является сокетом. Найдите файлы сокета с этой командой: find / -type s -print 2>/dev/null

D означает дверь

Ни одно найденное на моем хинду.

8
03.11.2013, 12:50
3 ответа

Переменные среды Linux всегда являются строками. Кавычки только необходимы, если у Вас есть специальные символы (метасимволы оболочки или пробел) в Вашей строке. Метасимволы Shell:

<>()[]{}*?$|&#\;`'"

С $ \и 'двойные кавычки не достаточны, поскольку они даже расширены в них. Там Вы нуждаетесь или в одинарных кавычках или выходите из них с \.

Как был отмечен в комментарии, удар имеет специальные переменные определенного типа, но они редко необходимы, и по умолчанию все переменные удара являются строками также.

6
27.01.2020, 20:11
  • 1
    +1, потому что ядро ответа корректно. Однако более усовершенствованные оболочки действительно имеют другие типы данных помимо просто строк. Bash позволяет Вам сказать вещи как typeset -i foo=2 получить целочисленную переменную $foo со значением 2. –  Warren Young 03.11.2013, 13:07
  • 2
    @WarrenYoung, В каком смысле то, что несколько отличающийся от foo=2? –  goldilocks 03.11.2013, 16:57
  • 3
    Nb. Нет такой вещи как "целочисленная переменная" в ударе: tldp.org/LDP/abs/html/untyped.html Они - все еще строки; typeset -i foo=2 точно то же как foo=2 и foo="2". –  goldilocks 03.11.2013, 17:04
  • 4
    @goldilocks Это не точно то же. Выполненный foo=0x${foo}; echo $foo" или foo=bar;echo $fooвидеть различие в поведении. В ударе существуют определенно целочисленные переменные определенного типа. –  jlliagre 03.11.2013, 19:06
  • 5
    @goldilocks declare -i x=123456789012345678901234567890;echo ${#x} отобразился бы 30 если это было верно, но это не имеет место. –  jlliagre 03.11.2013, 23:50

Bash не со строгим контролем типов; 1 единственная значительная разница между скаляром и составными типами (массивы). Скаляры всегда считают строками, но существуют "числовые строки", которые могут использоваться арифметически:

a="5"
b=10

echo "$a + $b = "$(($a+$b)); 

"Числовая строка" является просто строкой, которая содержит только цифры и так может быть преобразована в целочисленное значение. Все скалярные величины в ударе являются все еще просто строками, и кавычки в объявлении здесь не важны. a=5 EXCATLY то же как a="5". Если Вы выдерживаете сравнение $a и $b использование (например). -lt их рассматривают как числа. Если Вы сравниваете их использование < их рассматривают лексикографически. Это - оператор/контекст, который делает определение, не характеристику переменной.

Можно также объявить переменную с "целочисленным флагом", и это заставит заявленное значение интерпретироваться как арифметическое выражение:

x=10/2
echo "$x" # output: 10/2
declare -i x=10/2
echo "$x" # output: 5
declare -i x=what
echo "$x" # output: 0  

Впоследствии, что-либо присвоенное той переменной будет интерпретироваться арифметически:

a=5
declare -i b=10
a=$a/5
b=$b/5
echo "$a $b" #output: 5/5 2
a=hello
b=world
echo $a$b #output hello0

Но содержание переменной является все еще (числовой) строкой. Целочисленный флаг ограничивает содержание строки и влияет на интерпретацию значений, присвоенных ему.

1 Это не простой динамический контроль типов также, как демонстрирует случай заявленного целого числа. Возможно, мы могли назвать это своего рода утиным вводом, или, согласно Bash Усовершенствованное Руководство по созданию сценариев, это "не вводится".

5
27.01.2020, 20:11
  • 1
    Объявление переменной как целое число определенно имеет последующие последствия как с того времени, переменная не может использоваться для хранения (случайных) строк. спасибо –  jlliagre 03.11.2013, 19:13
  • 2
    @jlliagre Ya получил меня. Отредактированный. –  goldilocks 03.11.2013, 19:41

существует различие: попробовать

unset name
name="Michael Jackson" ; echo "$name" 

и

unset name #to reset name, see comments
name=Michael Jackson ; echo "$name"

Это очень отличается: на 2-м это пытается запустить команду "Jackson", передавая его "name=Michael" среда. Таким образом, это будет жаловаться что "Jackson: команда не нашла, что" я должен добавить unset name "сбрасывать" имя, как следующая строка name=Michael часть будет только передана команде "Jackson" (и только той команде) и поэтому НЕ сделана на уровне оболочки вызова! (который поэтому все еще имел бы name="Michael Jackson" от 1-й команды, если мы не задерживали его к "" перед нашей 2-й попыткой. Таким образом, "$name эха" смутно все еще отобразил бы "Michael Jackson", если бы мы не забыли что 1-я попытка.)

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

cd "${var}" 

намного лучше, чем

cd $var 

2-я версия тихо перешла бы к homedir вместо того, чтобы выступить, не определяется ли $var...

Затем только выньте окружающие двойные кавычки только, когда Вы знаете, что необходимо разделить каждого элементы переменной, т.е. в a:

for i in $var ; do something_using_i ; done
1
27.01.2020, 20:11

Теги

Похожие вопросы