LINUX.ORG.RU

Баг или фича: expr $456 + $457 = expr 56 + 57

 , ,


0

1

Случайно обнаружил интересную особенность в Bash с переменными. Выглядит это так:

expr $456 + $457

Ответ: 113.

Причём даже если брать любые цифры от 1 до 9: сумма ${1..9}56 и ${1..9}57 неизменно 113. Это работает с любыми цифрами — сумма, конечно же, другая, но первый разряд числа с долларом будто исчезает при вычислении. А куда исчезает? Кто знает?

Однако, с нулём такой фокус не проходит:

expr $056 + $057

Выводит ошибку: expr: non-integer argument

Почему так происходит?

Попутно выяснил, что умножение при помощи expr делается именно через обратный слэш:

expr 5 * 3 

— выдаст ошибку. А вот так:

expr 5 \* 3

— посчитает нормально.

Кто столкнулся с непонятным поведением expr при вычислениях, вот тут немного прояснили, откуда чего берётся, и что нужно делать, чтобы вычислялось нормально. Вкратце: нужно экранировать арифметические операторы.

★★★★★

Последнее исправление: Desmond_Hume (всего исправлений: 8)
Ответ на: комментарий от debugger

При том, что тут ты написал про «список команд». Вот я и уточнил, что за список команд (команд - во множественном числе). Впрочем и «список» подразумевает множественное число, в большинстве случаев.

Desmond_Hume ★★★★★
() автор топика
Ответ на: комментарий от Desmond_Hume

При том, что тут ты написал про «список команд». Вот я и уточнил, что за список команд (команд - во множественном числе). Впрочем и «список» подразумевает множественное число, в большинстве случаев.

Список из одного элемента тебя шокирует? Это ты ещё про пустой список не слышал, наверное.

debugger ★★★★★
()
Ответ на: комментарий от Desmond_Hume

Приводит, если в коде будут использоваться конструкции, которые используют $1, $2 в качестве позиционных параметров аргументов, а не в качестве чисел.

Ну ты прогер или кто? Если тебе нужны $1 и прочие, сохрани их. Потом восстановишь. Или не порть их. Главное, что ты можешь присвоить $1 и прочим значения, а уж надо тебе это или не надо — решай сам.

Вообще, ты задаёшь такие идиотские вопросы, что я сомневаюсь в твоей адекватности. Посмотрел на темы, тобой созданные за последнее время — там такая же дичь.

Походу, вот эта твоя фраза является ключевой:

Просто так люди документацию не читают, это не художественный роман.

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

debugger ★★★★★
()
Ответ на: комментарий от debugger

сомневаюсь в твоей адекватности. Если тебе нужны $1 и прочие, сохрани их. Потом восстановишь. Или не порть их.

Вот на этом моменте я тоже начал сомневаться.

Посмотрел на темы, тобой созданные за последнее время — там такая же дичь.

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

Если бы я был знающим, крутым прогером, как ты, я бы тут вообще тем не создавал, да и вряд ли был тут. Хотя, возможно, сжалился бы над неофитами, в паре случаев бы помог … но точно бы не ёрничал над ними. Ведь я же не родился крутым прогером, у нас борода растёт не сызмальства, тоже когда-то грыз гранит науки, было больно, некомфортно. Но не мне судить, я же не крутой прогер, как ты. У меня даже бороды нет, не люблю это дело. Может поэтому я не крутой прогер, не знаю.

Desmond_Hume ★★★★★
() автор топика
Ответ на: комментарий от Desmond_Hume

Ведь я же не родился крутым прогером…

С таким твоим подходом ты им никогда и не будешь. Я тебе писал, что документацию надо читать перед тем, как пользоваться инструментом, но ты, походу, не обратил на это внимания. Зачем читать доки? Это ж не художественный роман. Всегда можно создать на форуме тему, какой-нибудь доброхот подскажет решение, которое ты скопируешь как обезьяна, не понимая что там и к чему.

На остальной твой бред мне уже лень отвечать.

debugger ★★★★★
()
Ответ на: комментарий от debugger

Всегда можно создать на форуме тему

Ход твоих мыслей понятен. Непонятно только, почему ты считаешь себя крутым прогером?

Зачем читать доки?

Доки я читал. Но не обратил внимание на существенный абзац, который был оформлен «задним числом». Хорошо, что два человека читают что-то и видят по-разному, подмечают разные нюансы. Смотрят один и тот же фильм и подмечают разное. Если у тебя такое неприятие к форумам и коллективным обсуждениям, то какой смысл тут быть тебе? Ты ведь всё знаешь. Я утрирую. Судя по темам, которые ты создал, это далеко не так, но я тебе готов даже подыграть.

Desmond_Hume ★★★★★
() автор топика
Последнее исправление: Desmond_Hume (всего исправлений: 1)

Вкратце: нужно экранировать арифметические операторы.

Это путь слабых духом

Вот настоящее решение:

$ ln -sf $(which bash) 0; PATH=.:$PATH; 0 --init-file <(echo "set -f -- 1 2 3 4 5 6 7 8 9")
$ 
$ expr $456 + $457
913
$ expr $056 + $057
113
$ expr 5 * 3 
15
$ expr 5 \* 3
15
$ 
alx777 ★★
()
Ответ на: комментарий от alx777

Это да, но ходить задом наперёд, на четвереньках, и вправду как-то неудобно, по-моему. Хотя, честно признаюсь, я так ходить не пробовал, может это и удобно.

Desmond_Hume ★★★★★
() автор топика
Ответ на: комментарий от Desmond_Hume

Это да, но ходить задом наперёд, на четвереньках, и вправду как-то неудобно, по-моему. Хотя, честно признаюсь, я так ходить не пробовал, может это и удобно.

Диковинные задачи требуют диковинных решений

alx777 ★★
()
Ответ на: комментарий от alx777

По-моему, проще и короче так: expr 456 \* 457, если задача посчитать. Про переменные в теме было написано не потому, что хотелось считать именно так, со значком переменных, а хотелось узнать, почему так происходит. Никто так толком не объяснил, за исключением 1-2 человека, которые немного пролили свет на суть, но и то … только косвенно. Я до сих пор не понимаю, почему bash не интерпретирует это как ошибку в синтаксисе и пытается считать, и даже считает (по-своему).

Desmond_Hume ★★★★★
() автор топика

Всё, кажись, дошло. Он пропускает $1-9. Сейчас попробовал $1ls команду и вывело ls, только в монохромном режиме. А почему цветной схемы нет? Я так понимаю, цветовую настройку он проредил пустой строкой, поэтому цвета не применились, да?

Desmond_Hume ★★★★★
() автор топика
Последнее исправление: Desmond_Hume (всего исправлений: 1)
Ответ на: комментарий от Desmond_Hume

если задача посчитать.

Если задача посчитать в bash, то каким боком тут ″expr″? В bash есть ″ARITHMETIC EVALUATION″:

echo $(( 6 * 7 )) 
или
(( n=6*7 )) ; echo $n
или
(( n=6*7 )) ; echo $((n+5))
там и пробелы не везде нужны и экранировать не нужно и ″$″ к именам обычных переменных можно не добавлять.

mky ★★★★★
()
Ответ на: комментарий от mky

Можно считать хоть через bc и ещё много какими способами. Предложенный вами способ длиннее:

1. echo $(( 6 * 7 ))
2. (( n=6*7 )) ; echo $n 
3. expr 6 \* 7

Очевидно, что 3-ий вариант короче.

Desmond_Hume ★★★★★
() автор топика