web-dev-qa-db-ja.com

シェルで文字列を整数に

私は現在「ダウンロードマネージャーのコマンドラインインターフェイス」を意味する「dmCLI」というプロジェクトに取り組んでいます。 curlを使用してファイルをマルチパートダウンロードしています。そして、私は私のコードで問題を抱えています。文字列をintに変換できません。

これが私の完全なコードです。また、コードをGithub Repoにアップロードしました。ここにあります: dmCLI GitHub Repository

#!/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/

A HEAD request to http://127.0.0.1:404/ returns:Content-Length:283、Accept-Range:bytes

DmCLIは値を取得するために機能しますが、その値にアクセスしたい場合は機能しません。

単純なアクションは次のように機能します。

echo "$contentlength"

しかし、これを使用してそれにアクセスすることはできません:

echo "$contentlength bytes"

そしてここ:

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

9を返しますが、292を期待しています。問題はどこにありますか。なぜ機能しないのですか?

2
A. Taha Baki

以下の正規表現は、バイト数のみを抽出します。

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

上記の変更後、contentlength変数は10進数のみで構成され(先頭の0が削除されるため、シェルは数値を8進数と見なしません)、以下の2行で同じ結果が表示されます。

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

echo "$((contentlength/9))"
2
Jay jargot
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 "
0
pizdelect