expr
parece não gostar de parênteses (usado em matemática para prioridade explícita do operador):
expr 3 * (2 + 1)
bash: syntax error near unexpected token `('
Como expressar a prioridade do operador no bash?
shell
quoting
arithmetic
expr
Nicolas Raoul
fonte
fonte
let
. Não é mais padrão ou portátil do que(( a = 3 * (2 + 1) ))
(ambos vêmksh
e estão disponíveis apenas em ksh, bash e zsh) e é menos legível ou fácil de citar. Usea=$((3 * (2 + 1)))
para ser portátil.((a = 3 * (2 + 1) ))
e outra para portabilidadea=$((3 * (2 + 1)))
); portanto, não é uma nota contra você ou sua resposta, mas contra a resposta selecionada. e melhor marcador.a=1 $[a+2]
oua=1 b=2 $[a+b]
. É o motivo deles para evitar essa sintaxe?Você pode usar a expansão aritmética.
Na minha opinião pessoal, isso parece um pouco melhor do que usar
expr
.De
man bash
fonte
Não há razão para usar
expr
aritmética em conchas modernas.POSIX define o
$((...))
operador de expansão. Então você pode usá-lo em todos os shells compatíveis com POSIX (sh
todos os gostos modernos do Unix, dash, bash, yash, mksh, zsh, posh, ksh ...).ksh
também introduziu umlet
built-in que recebe o mesmo tipo de expressão aritmética, não se expande para algo, mas retorna um status de saída com base no fato de a expressão ser resolvida como 0 ou não, como emexpr
:No entanto, como a citação o torna estranho e pouco legível (não na mesma extensão que é
expr
claro),ksh
também introduziu uma((...))
forma alternativa:que é muito mais legível e deve ser usado.
let
e((...))
estão disponíveis apenas emksh
,zsh
ebash
. A$((...))
sintaxe deve ser preferida se a portabilidade para outros shells for necessária,expr
apenas necessária para shells pré-POSIX tipo Bourne (normalmente o shell Bourne ou versões anteriores do shell Almquist).Na frente não Bourne, existem algumas conchas com o operador aritmético embutido:
csh
/tcsh
(na verdade, o primeiro shell Unix com avaliação aritmética integrada):akanga
(com base emrc
)como uma nota de histórico, a versão original do shell Almquist, publicada na usenet em 1989, tinha um
expr
built-in (na verdade, foi mesclado comtest
), mas foi removida mais tarde.fonte
: $((a = a*2))
?$((...))
como zsh, ksh93 ou yash.expr
é um comando externo, não é uma sintaxe especial do shell. Portanto, se você desejaexpr
ver caracteres especiais do shell, é necessário protegê-los da análise do shell, citando-os. Além disso,expr
precisa que cada número e operador sejam passados como um parâmetro separado. Portanto:A menos que você esteja trabalhando em um sistema unix antigo das décadas de 1970 ou 1980, há muito pouco motivo para usar
expr
. Antigamente, os shells não tinham uma maneira integrada de executar aritmética, e você precisava chamar oexpr
utilitário. Todos os shells POSIX possuem aritmética integrada por meio da sintaxe de expansão aritmética .A construção se
$((…))
expande para o resultado da expressão aritmética (escrita em decimal). O Bash, como a maioria dos shells, suporta apenas o módulo aritmético inteiro 2 64 (ou o módulo 2 32 para versões mais antigas do bash e alguns outros shells em máquinas de 32 bits).O Bash oferece uma sintaxe de conveniência adicional quando você deseja executar atribuições ou testar se uma expressão é 0, mas não se importa com o resultado. Essa construção também existe no ksh e no zsh, mas não no sh simples.
Além da aritmética inteira,
expr
oferece algumas funções de manipulação de string. Eles também são incluídos nos recursos dos shells POSIX, exceto um:expr STRING : REGEXP
testa se a string corresponde ao regexp especificado. Um shell POSIX não pode fazer isso sem ferramentas externas, mas o bash pode com[[ STRING =~ REGEXP ]]
(com uma sintaxe regexp diferente -expr
é uma ferramenta clássica e usa BRE, o bash usa ERE).A menos que você esteja mantendo scripts executados em sistemas de 20 anos, não é necessário saber que isso
expr
já existiu. Use aritmética de casca.fonte
expr foo : '\(.\)'
também faz extração de texto.bash
'sBASH_REMATCH
consegue algo similar. Também faz comparação de strings, o que o POSIX[
não faz (embora se possa imaginar maneiras de usásort
-lo).Use parênteses com aspas:
As aspas impedem que o bash interprete os parênteses como sintaxe do bash.
fonte
expr
linha de comando devem ser separados por espaços; tão; por exemplo,expr 3 "*" "(2" "+" "1)"
não vai funcionar . (Também, BTW, você provavelmente não precisa citar o+
.)while
e[[
são sintaxe. Se fossem palavras-chave, não seriam interpretadas como tal nos argumentos de comando. Você precisa de aspas para que o bash não as analise, mas veja uma string literal.Se você tem bc ..
fonte