dfx (Dfinity Canister SDK)をバージョン指定してインストールする方法を整理し、その実行コマンドの中身を読み解きます。
こんにちは、@bioerrorlogです。
Dfinity Canister SDK / dfxをインストールするときはいつも、脳を空っぽにしてドキュメントにあるコマンドをコピペしていました。
内容を気にせずにコマンド実行するのも据わりが悪いので、一度くらいはインストールコマンドを読み解いておこうと思いました。
dfxバージョンを指定してインストールするコマンドをメモし、その実行内容を整理していきます。
ドキュメントの通り、例えばバージョン0.8.2をインストールするときは次のコマンドを実行します。
DFX_VERSION=0.8.2 sh-ci"$(curl -fsSL https://sdk.dfinity.org/install.sh)"
環境変数DFX_VERSIONに任意のバージョンを指定することで、指定のdfxバージョンをインストールすることができます。
では、上記インストールコマンドの処理内容を読み解いていきます。
DFX_VERSION=0.8.2<実行コマンド>
このようにコマンドを実行することで、環境変数DFX_VERSIONにバージョン番号を代入した状態で以降のコマンドが実行されます。exportコマンドに環境変数宣言部分を切り出したとしても、インストールするバージョンが指定できる点は同じです。
exportDFX_VERSION=0.8.0sh-ci"$(curl -fsSL https://sdk.dfinity.org/install.sh)"
sh-ci"$(xxxxx)"
この部分ではshコマンドによって"$(xxxxx)"から受け渡される文字列がshellプロセスとして実行されます。
-cオプションによって(標準入力でなく)後続の文字列をshellで実行することを指定できます。
-iオプションはコマンドをインタラクティブに実行することを指定するオプションです。が、現状のインストールコマンドでは特にターミナルとやり取りする要素はないので不要なのでは...?と思っています。(実際、-i部分を抜いてコマンドを実行しても変わりなくインストールできます。)
"$(xxxxx)"では、その内部を評価した後の文字列が渡されます。(shellにおいては、ダブルクォーテーション部分はその評価後の状態が、シングルクォーテーションでは内部がそのままの文字列として渡されます。)
curl-fsSL https://sdk.dfinity.org/install.shこの部分でcurlコマンドによってdfxのインストールスクリプトをダウンロードしています。
-fオプションは、リクエストが失敗したときにはなにも出力させず、代わりにexitコード22を返却するようにするものです。(リクエストが失敗したときにエラー通知用HTMLがサーバーから返されたとしても、何も出力しない挙動にすることが出来ます)
-sSによって進捗メーター表示をなくします。(厳密には-sによって進捗メーターとエラーメッセージの表示をなくし、加えて-Sを指定することでエラーメッセージは表示するよう設定されます。)
-Lは、リクエストページが移動してた場合に新しい場所に対して再リクエストを投げるようにするオプションです。
※各オプションの詳しい説明はmanページや下記リンクが参考になります:
explainshell.com - curl -fsSL https://sdk.dfinity.org/install.sh
上記curlコマンドによってhttps://sdk.dfinity.org/install.shから取得され、shコマンドによって実行されるdfxのインストールスクリプトの中身は以下です。
長いスクリプトなので内容は網羅しませんが、次の部分でインストール先ディレクトリにdfx実行ファイルを配置し、dfxがインストールされています。
$MV"$_dfx_file""${_install_dir}"2>/dev/null\
スクリプト全文:
#!/usr/bin/env sh## 000_header.sh#### Borrowed from rustup (https://sh.rustup.rs)#### This is just a little script that can be downloaded from the internet to## install dfx. It just does platform detection, downloads the installer## and runs it.#### You are NOT AUTHORIZED to remove any license agreements or prompts from the following script.##set-u## install/010_manifest.shget_tag_from_manifest_json() {cat \| tr-d'\n' \|grep-o"\"$1\":[[:space:]]*\"[a-zA-Z0-9.]*" \|grep-o"[0-9.]*$"}## 020_flags.shDFX_BOOL_FLAGS=""define_flag_BOOL() {local VARNAMEVARNAME="flag_$(echo"$1"| tr /a-z/ /A-Z)"eval"$VARNAME=\${$VARNAME:-}"DFX_BOOL_FLAGS="${DFX_BOOL_FLAGS}--${1}$VARNAME$2"}get_flag_name() {echo"$1"}get_var_name() {echo"$2"}read_flags() {while [-n"$*"]; dolocal ARG=$1shiftOLD_IFS="$IFS"IFS=$'\n'for linein${DFX_BOOL_FLAGS};do["$line"]||breakIFS="$OLD_IFS"FLAG="$(get_flag_name"$line")"VARNAME="$(get_var_name"$line")"if ["$ARG"=="$FLAG"];theneval"$VARNAME=1"fidonedone}## 100_log.shlog() {if "$_ansi_escapes_are_valid";thenprintf"\33[1minfo:\33[0m %s\n""$1"1>&2elseprintf'%s\n'"$1"1>&2fi}say() {printf'dfinity-sdk: %s\n'"$1"}warn() {if$_ansi_escapes_are_valid;thenprintf"\33[1mwarn:\33[0m %s\n""$1"1>&2elseprintf'%s\n'"$1"1>&2fi}err() { say"$1">&2exit1}## 110_assert.shneed_cmd() {if ! check_cmd"$1";then err"need '$1' (command not found)"fi}check_cmd() {command-v"$1">/dev/null2>&1}assert_nz() {if [-z"$1"];then err"assert_nz$2";fi}ensure() {if !"$@";then err"command failed:$*";fi}ignore() {"$@"}## 200_downloader.shdefine_flag_BOOL"insecure""Allows downloading from insecure URLs, either using HTTP or TLS 1.2 or less."check_help_for() {local _cmdlocal _arglocal _ok_cmd="$1"_ok="y"shiftifcheck_cmd sw_vers;thencase"$(sw_vers -productVersion)"in 10.13*);; 10.14*);; 10.15*);; 11.*);; *) warn"Detected OS X platform older than 10.13 (High Sierra)"_ok="n";;esacfifor _argin"$@";doif !"$_cmd"--help|grep-q--"$_arg";then_ok="n"fidonetest"$_ok"="y"}check_support_for() {local err="$1"shiftlocal cmd="$*"!($cmd2>&1|grep"$err">/dev/null)}downloader() {local _dldifcheck_cmd curl;then_dld=curlelif check_cmd wget;then_dld=wgetelse_dld='curl or wget'fiif ["$1"= --check];then need_cmd"$_dld"elif["$_dld"=curl];thenifcheck_help_for curl--proto--tlsv1.2;then curl--proto'=https'--tlsv1.2--silent--show-error--fail--location"$1"--output"$2"elif!["$flag_INSECURE"];then warn"Not forcing TLS v1.2, this is potentially less secure" curl--silent--show-error--fail--location"$1"--output"$2"else err"TLS 1.2 is not supported on this platform. To force using it, use the --insecure flag."fielif["$_dld"=wget];thenifcheck_help_for wget--https-only--secure-protocol;then wget--https-only--secure-protocol=TLSv1_2"$1"-O"$2"elif!["$flag_INSECURE"];then warn"Not forcing TLS v1.2, this is potentially less secure" wget"$1"-O"$2"else err"TLS 1.2 is not supported on this platform. To force using it, use the --insecure flag."fielse err"Unknown downloader"fi}## 999_footer.shSDK_WEBSITE="https://sdk.dfinity.org"DFX_RELEASE_ROOT="${DFX_RELEASE_ROOT:-$SDK_WEBSITE/downloads/dfx}"DFX_MANIFEST_JSON_URL="${DFX_MANIFEST_JSON_URL:-$SDK_WEBSITE/manifest.json}"DFX_VERSION="${DFX_VERSION:-}"SCRIPT_COMMIT_DESC="aff944417cccf34abe58dac9283fdf2b92d10458"get_tag_from_manifest_json() {cat \| tr-d'\n' \|grep-o"\"$1\":[[:space:]]*\"[a-zA-Z0-9.]*" \|grep-o"[0-9.]*$"}get_manifest_version() {local _version_version="$(downloader"${DFX_MANIFEST_JSON_URL}" -| get_tag_from_manifest_json latest)"||return2printf %s"${_version}"}validate_install_dir() {local dir="${1%/}"if ![-d"$dir"];thenif !mkdir-p"$dir";thenif type sudo>/dev/null;then sudomkdir-p"$dir"fififi![-d"$dir"]&&return1![-w"$dir"]&&return2case":$PATH:"in *:$dir:*);; *)return3;;esacreturn0}sdk_install_dir() {if ["${DFX_INSTALL_ROOT:-}"];then validate_install_dir"${DFX_INSTALL_ROOT}"printf %s"${DFX_INSTALL_ROOT}"elif validate_install_dir /usr/local/bin;thenprintf %s /usr/local/binelif["$(uname -s)"=Darwin];then validate_install_dir /usr/local/binprintf %s /usr/local/binelif validate_install_dir /usr/bin;thenprintf %s /usr/binelseprintf %s"${HOME}/bin"fi}main() {_ansi_escapes_are_valid=falseif [-t2];thenif ["${TERM+set}"='set'];thencase"$TERM"in xterm*| rxvt*| urxvt*| linux*| vt*)_ansi_escapes_are_valid=true;;esacfifi read_flags"$@" log"Executing dfx install script, commit:$SCRIPT_COMMIT_DESC" downloader--check need_cmd uname need_cmd mktemp need_cmdchmod need_cmdmkdir need_cmdrm need_cmd tar need_cmd gzip need_cmd touch get_architecture||return1local _arch="$RETVAL" assert_nz"$_arch""arch"if [-z"${DFX_VERSION}"];thenDFX_VERSION=$(get_manifest_version)fi log"Version found:$DFX_VERSION"local _dfx_url="${DFX_RELEASE_ROOT}/${DFX_VERSION}/${_arch}/dfx-${DFX_VERSION}.tar.gz"local _dir_dir="$(mktemp -d2>/dev/null|| ensure mktemp -d -t dfinity-sdk)"local _dfx_archive="${_dir}/dfx.tar.gz"local _dfx_file="${_dir}/dfx" log"Creating uninstall script in ~/.cache/dfinity"mkdir-p"${HOME}/.cache/dfinity/" install_uninstall_script log"Checking for latest release..." ensuremkdir-p"$_dir" ensure downloader"$_dfx_url""$_dfx_archive" tar-xf"$_dfx_archive"-O>"$_dfx_file" ensurechmod u+x"$_dfx_file"local _install_dir_install_dir="$(sdk_install_dir)"printf"%s\n""Will install in:${_install_dir}"mkdir-p"${_install_dir}"||trueif [-w"${_install_dir}"];thenMV="mv"elseif !type sudo>/dev/null;then err"Install directory '${_install_dir}' not writable and sudo command not found"fiMV="sudo mv"fi$MV"$_dfx_file""${_install_dir}"2>/dev/null \|| err"Failed to install the DFINITY Development Kit: please check your permissions and try again." log"Installed$_install_dir/dfx" ignorerm-rf"$_dir"}get_architecture() {local _ostype _cputype _arch_ostype="$(uname -s)"_cputype="$(uname -m)"if ["$_ostype"=Darwin]&&["$_cputype"=i386];thenifsysctl hw.optional.x86_64|grep-q': 1';then_cputype=x86_64fifiif ["$_ostype"=Darwin]&&["$_cputype"=arm64];then_cputype=x86_64ficase"$_ostype"in Linux)_ostype=linux;; Darwin)_ostype=darwin;; *) err"unrecognized OS type:$_ostype";;esaccase"$_cputype"in x86_64| x86-64| x64| amd64)_cputype=x86_64;; *) err"unknown CPU type:$_cputype";;esac_arch="${_cputype}-${_ostype}"RETVAL="$_arch"}install_uninstall_script() {set+ulocal uninstall_file_pathlocal uninstall_scriptuninstall_script=$(cat<<'EOF'#!/usr/bin/env shuninstall() { check_rm "${DFX_INSTALL_ROOT}/dfx" check_rm "${HOME}/bin/dfx" check_rm /usr/local/bin/dfx /usr/bin/dfx clean_cache}check_rm() { local file for file in "$@" do [ -e "${file}" ] && rm "${file}" done}clean_cache() { if [ -z "$HOME" ]; then exit "HOME environment variable unset." fi rm -Rf "${HOME}/.cache/dfinity"}uninstallEOF)set-u assert_nz"${HOME}"uninstall_file_path="${HOME}/.cache/dfinity/uninstall.sh" log"uninstall path=${uninstall_file_path}"rm-f"${uninstall_file_path}"printf"%s""$uninstall_script">"${uninstall_file_path}" ensurechmod u+x"${uninstall_file_path}"}main"$@" ||exit$?
以上、dfxをバージョン指定してインストールする方法をメモし、その実行コマンドの中身を読み解きました。
dfxのインストール方法は非常シンプルかつ処理時間も短いので、色々なバージョンの実験が気軽にできます。
触って遊んで、その挙動に慣れ親しんでいきたいものです。
[関連記事]
Installing the SDK | Internet Computer Home
引用をストックしました
引用するにはまずログインしてください
引用をストックできませんでした。再度お試しください
限定公開記事のため引用できません。