Estou trabalhando em um script e há algum tempo quero pegar a entrada do usuário e usar como um valor inteiro com um contador da seguinte forma:
read -p "How many bytes would you like you replace :> " $numOfBytes
echo "$numOfBytes bytes to replace"
while [ $counter -le $numOfBytes ]
do
echo "testing counter value = $counter"
let $counter++
done
Pelo que entendi, atualmente não funciona porque está usando a variável numOfBytes como uma string.
Preciso converter a string para um int de alguma forma? É possível fazer algo assim? Existe uma alternativa?
Você deseja ler um inteiro e, em seguida, fazer um loop de 1 para esse inteiro, imprimindo o número em cada iteração:
Observe como o
$
não é usado ao ler o valor. Com$var
você obtém o valor da variávelvar
, masread
precisa saber o nome da variável para ler, não seu valor.ou, com um loop while,
O
(( ... ))
inbash
é um contexto aritmético. Em tal contexto, você não precisa colocar$
suas variáveis, e os valores das variáveis serão interpretados como inteiros.ou, com
/bin/sh
,O
-le
teste ("menor ou igual") precisa atuar em duas expansões de variáveis entre aspas (neste código). Se eles não estivessem entre aspas, como em[ $i -le $num ]
, então, se qualquer uma das variáveis contivesse um caractere de shell ou um espaço, você poderia obter resultados inesperados ou erros. Além disso, as aspas protegem os números caso aIFS
variável contenha dígitos.Perguntas relacionadas:
Para responder à pergunta específica:
A resposta é não. As variáveis de shell são todas strings, mas dependendo do contexto em que são usadas, elas podem ser tratadas como números inteiros ou strings. No caso do
-le
operador para[
comando (também conhecido comotest
comando), as variáveis serão tratadas como números inteiros.Seu script precisa inicializar a
counter
variável, soltá - la$
de e removê -la de .numOfBytes
read
$
let
Isso funciona assim:
Observe que, devido à
let
palavra -chavebash
/ksh
, isso torna o script menos portátil. Seria aconselhável fazer uso da expansão aritméticacounter=$((counter+1))
, que faz parte do padrão Shell Language do POSIX (seção 2.6.4).Veja também: https://askubuntu.com/a/939299/295286
Como o Storm Dragon apontou, o fato de as variáveis do shell serem tratadas dependendo de seu contexto também implica que a entrada do usuário precisa ser higienizada. Uma maneira possível é tomar
numOfBytes
em declaração portátilcase
como nesta resposta , que se encarrega de determinar se a entrada é realmente um dígito.Bash realmente não tem tipos atribuíveis. A variável é o tipo de sua declaração. Então, se você declarar uma variável como
abc
, é uma string. Se você declarar como138
, é um int. O Bash realmente não lida com decimais, portanto, se você declarar a variável como138.0
, ela a tratará como uma string.Portanto, você precisa ter cuidado com a entrada do usuário, porque não pode fazer um loop de
0
paraabc
. Aqui está um exemplo que deve fornecer alguma verificação de erro e incrementar os bytes em um loop.