編集:$ HOME / .binと言ったところで$ HOME / binを作成したか、それと同等の内容が機能しなければなりませんでした。 IE、ユーザーの PATH のユーザー書き込み可能ディレクトリ。
そのため、APIクライアントとしてデプロイするbashスクリプトがあります。現在のバージョンは次のようにインストールされますcurl -s http://api.blah.com/install | sudo sh
。おそらく6つの異なるパッケージ管理システムを処理して、特定の時点でのみ機能するように努力しますapt-get
。brew install
しかし、今はこのソリューションが複数のシステムで動作したいので、1行を使用します。しかし、sudoがまったくない場合や、cygwinやMacなどのシステムにsudoが設定されていないユーザーもかなり多いです。
シナリオは、ユーザーが自分のAPIに参加してクレジットカード情報を入力することです。リファレンス実装とAPIを試してみるか、コマンドラインを使用して仮想マシンとDockerコンテナをデプロイする方法として使用されるAPI用のbashクライアントがあります。ユーザーがAPIクライアントを簡単にインストールできる方法を作成したいと思います。
たとえば、npmは1行のインストールでしたcurl http://npmjs.org/install.sh | sh
。 Homebrewには1行のインストーラもありますruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"
(参照:http://brew.sh)。
私のインストールスクリプトはAPIクライアントスクリプトをダウンロードして/usr/binに保存し、実行可能にします。しかし、sudo関連の問題とグローバルインストールが実際には必要ないという事実に基づいて、ユーザーの$ HOME / .binまたは$ HOME / local / binにインストールしたい(既存のファイルがない場合は作成)。等しい)。
これは私の現在のインストールスクリプトです。
#!/bin/bash
BASE="https://api.blah.com"
sudo bash -c "curl -s $BASE/mycmd > /usr/bin/mycmd"
sudo chmod uga+x /usr/bin/mycmd
私の最初の考えは、現在多くのユーザーがzshを使用していることです。したがって、$ HOME / .binを含むようにPATHを更新するために〜/ .bashrcに行を追加または変更すると、これらのシステムでは機能しません。
だから質問をもう一度申し上げると、そのユーザーの PATH ($HOME/local/bin またはデフォルトで PATH で使用できるすべての項目) のユーザー書き込み可能ディレクトリにスクリプトをダウンロードしてインストールし、そのスクリプトがその PATH にあることを確認し、要件を使用するには、どのコードを使うべきですか? (または少なくともUnixプロンプト(sudoは不要)のようなものがある場合は、ほぼすべての人のシステムで動作するという強い欲求)?
一部の人はPATHを変更するのが悪いと思うので、特定のパスディレクトリを含めるようにPATHを自動的に変更するのではなく、可能であればすでにユーザーのPATHにあるそのシステムのデフォルトの$ HOME / whatever / binにインストールしたいと思います。
とても感謝しています!
答え1
あなたの環境に自分自身を注入するプログラムを指す言葉があります:ウイルス。
単に ~/bin/ (手動インストールスクリプトの歴史的事実上標準) または ~/.local/bin/ (ルート以外のパッケージマネージャがインストールしたスクリプトの最新の竣工標準) にインストールするだけです。通常、ユーザーフレンドリーなディストリビューションには、すでに $PATH にこれらのいずれかまたは両方があります。
あるいは、より良い方法は、インタラクティブにユーザーにインストールプレフィックスを求めるメッセージを表示することです。
答え2
スクリプト自体で$ PATHを照会しないのはなぜですか?ユーザーの$ PATH(通常~/bin
または~/.local/bin
)に書き込み可能なディレクトリがあることを確認してください。もしそうなら、そこにインストールすればいいでしょう。それ以外の場合はメッセージが表示されます。一部のディストリビューション(Ubuntuなど)では、~/bin
$ PATHにディレクトリがある場合は自動的に追加すると思いますが、常にそうであるとは想定できません。
~/.profile
唯一のオプションは、多くのシェルで選択したディレクトリを編集して、$ PATHにインストールしたディレクトリを追加することです。忘れてください~/.bashrc
。 bashに限定されず、$ PATHを設定する必要もありません。しかし、このようにグローバル変数を編集するのは良いことではありません。
最良の方法は、書き込み可能なディレクトリを確認し、見つからない場合はメッセージを表示することです。
答え3
shへの配管は問題があります。安全観点から、もう少し微妙に、堅牢性とエラー処理視点。
インストールスクリプトに3行しかない場合、ユーザーは3行だけ実行するようにしたいですか?彼らはすでにcurl
コマンドをコピーして貼り付けています。コピーして貼り付ける行を少し長くするには、次の手順を実行します。
mkdir -p ~/bin && curl -s "https://api.blah.com/mycmd" > ~/bin/mycmd && chmod ugo+x ~/bin/mycmd
ほとんどのディストリビューションでは、~/bin/
ディレクトリが存在する限りこの情報が入力されます。最悪の場合は、ユーザーが自分のスコープに該当しない場合でも、ログアウトしてから$PATH
再度ログインしてディレクトリを追加する必要があります。 Unixに精通している場合は、パスにいることを確認し、追加の6文字を削除できることがわかります。彼らがUnixに初めて接していて、ディストリビューションが役に立たず、6つの追加文字を入力する必要がある場合、おそらくそれほど問題ではないでしょう。$PATH
$PATH
~/bin/mycmd
mycmd
~/bin/
誰かがrootアクセス権を持っていて他の場所にインストールしたい場合は、上記の行を~/bin/
変更するのは簡単です。変更方法がわからない場合は、ルートファイルシステムを変更しないでください。
答え4
結局のところ、スタートページには2つのオプションがありました。 ~/.local/bin などを探して ~/.zshrc や ~/.bashrc の PATH に追加するなど、インストーラスクリプトの機能を簡単に説明します。また、スクリプトを使用せずに手動でインストールするオプションも提供し、簡単な手順も提供しました。
サイレントインストーラを実行するには、ユーザーは次のコマンドを貼り付けて実行できます。
curl -s https://thesite.com/installmycmd > /tmp/inst; source /tmp/inst
以下はinstallmycmdスクリプトです。
#!/bin/bash
BASE="https://thesite.com"
declare -a binddirs
bindirs=($HOME/bin $HOME/.local/bin $HOME/.bin)
founddir="false"
findprofile() {
profiles=($HOME/.zshrc $HOME/.bashrc $HOME/.bash_login $HOME/.login $HOME/.profile)
for prof in "${profiles[@]}"; do
if [ -f "$prof" ]; then
echo "$prof"
return
fi
done
touch $HOME/.profile
echo "$HOME/.profile"
}
for bindir in "${bindirs[@]}"; do
if [ -d "$bindir" ]; then
founddir=true
echo "You have a user bin dir here $bindir."
whichprofile=$(findprofile)
pathline=$(grep ^PATH= $whichprofile)
if [[ ! $pathline == *$bindir* ]]; then
echo "Appending $bindir to PATH in $whichprofile"
echo -e "\nexport PATH=\$PATH:$bindir" >> "$whichprofile"
NEWPATH=$PATH:$bindir
export NEWPATH
else
echo "That is in your PATH in $whichprofile"
fi
break;
fi
done
if [ ! -z $NEWPATH ]; then
echo "Exported PATH: $NEWPATH"
export PATH=$NEWPATH
fi
if [[ "$founddir" == "false" ]]; then
echo "Could not find ~/.bin or ~/.local/bin or ~/bin."
echo "Creating ~/.local/bin and adding to PATH"
mkdir -p $HOME/.local/bin
bindir=$HOME/.local/bin
whichprofile=$(findprofile)
echo "Appending PATH edit to $whichprofile"
echo -e "\nexport PATH=$PATH:$HOME/.local/bin" >> "$whichprofile"
export PATH=$PATH:$HOME/.local/bin
fi
bash -c "curl -s $BASE/JSON.sh > $bindir/JSON.sh"
bash -c "curl -s $BASE/mycmd > $bindir/mycmd"
chmod ug+x $bindir/mycmd
chmod ug+x $bindir/JSON.sh