Shell에서 문자열을 정수로 변환

Shell에서 문자열을 정수로 변환

저는 현재 "다운로드 관리자 명령줄 인터페이스"를 의미하는 "dmCLI"라는 프로젝트를 진행 중입니다. 컬을 사용하여 파일을 부분적으로 다운로드하고 있습니다. 내 코드에 문제가 있습니다. 문자열을 정수로 변환할 수 없습니다.

여기 내 완전한 코드가 있습니다. 또한 내 코드를 Github Repo에 업로드했습니다. 여기있어: dmCLI GitHub 저장소

#!/bin/bash
RED='\033[0;31m'
NC='\033[0m'

help() {
    echo "dmcli [ FILENAME:path ] [ URL:uri ]"
}

echo -e "author: ${RED}@atahabaki${NC}"
echo -e "     __      _______   ____"
echo -e " ___/ /_ _  / ___/ /  /  _/"
echo -e "/ _  /  ' \/ /__/ /___/ /  "
echo -e "\_,_/_/_/_/\___/____/___/  "
echo -e "                           "
echo -e "${RED}Downloading${NC} has never been ${RED}easier${NC}.\n"

if [ $# == 2 ]
then
    filename=$1;
    url=$2
    headers=`curl -I ${url} > headers`
    contentlength=`cat headers | grep -E '[Cc]ontent-[Ll]ength:' | sed 's/[Cc]ontent-[Ll]ength:[ ]*//g'`
    acceptranges=`cat headers | grep -E '[Aa]ccept-[Rr]anges:' | sed 's/[Aa]ccept-[Rr]anges:[ ]*//g'`
    echo -e '\n'
    if [ "$acceptranges" = "bytes" ]
    then 
        echo File does not allow multi-part download.   
    else
        echo File allows multi-part download.
    fi
    echo "$(($contentlength + 9))"
    # if [acceptranges == 'bytes']
    # then
    # divisionresult = $((contentlength/9))
    # use for to create ranges...
else 
    help
fi

# First get Content-Length via regex or request,
# Then Create Sequences,
# After Start Downloading,
# Finally, re-assemble to 1 file.

contentlength의 값을 9로 나누고 싶습니다. 나는 다음을 시도했다:

echo "$(($contentlength/9))"

다음과 같은 오류가 발생합니다.

/9") 구문 오류: 잘못된 산술 연산자(오류는 "로 표시됨)

node.js로 작성된 localhost를 사용하고 있습니다. 헤더 응답을 추가했습니다. 요청된 파일의 Content-Length를 반환하며 위의 dmCLI.sh는 Content-Length 값을 올바르게 가져옵니다.

./dmcli.sh home.html http://127.0.0.1:404/

HEAD 요청http://127.0.0.1:404/반환: 콘텐츠 길이: 283, 허용 범위: 바이트

dmCLI는 값을 가져오는 데 사용되지만 해당 값에 액세스하려고 하면 작동하지 않습니다.

간단한 조작은 다음과 같습니다.

echo "$contentlength"

하지만 다음을 사용하여 액세스할 수 없습니다.

echo "$contentlength bytes"

그리고 여기:

echo "$(($contentlength + 9))"

9를 반환하지만 292를 예상했습니다. 문제가 무엇인가요? 왜 작동하지 않나요?

답변1

다음 정규식은 바이트 수와 숫자만 추출합니다.

contentlength=$(
  LC_ALL=C sed '
    /^[Cc]ontent-[Ll]ength:[[:blank:]]*0*\([0-9]\{1,\}\).*$/!d
    s//\1/; q' headers
)

위의 변경 후 contentlength변수는 10진수로만 구성되므로(셸이 숫자를 8진수로 처리하지 않도록 선행 0을 제거함) 다음 두 줄은 동일한 결과를 표시합니다.

echo "$(($contentlength/9))"

echo "$((contentlength/9))"

답변2

headers=`curl -I ${url} > headers`
contentlength=`cat headers | grep -E '[Cc]ontent-[Ll]ength:' | sed 's/[Cc]ontent-[Ll]ength:[ ]*//g'`
echo "$(($contentlength/9))"

다음과 같은 오류가 발생합니다.

/9")syntax error: invalid arithmetic operator (error token is "

HTTP 헤더는 항상 LF가 아닌 CR/LF로 끝납니다. `cat headers | ...`명령 확장은 후행 LF를 제거하지만 CR을 유지하므로 이상한 오류가 발생합니다.

% var=`printf "%s\r\n" 333`
% echo var={$var}
}ar={333
% echo "$((var / 3))"
")syntax error: invalid arithmetic operator (error token is "

관련 정보