
Ubuntu日本語フォーラム
ログインしていません。
端末起動時、以前打ったコマンドのスペルミスを指摘するエラーが出ます。
"コマンド'exprt'は見つかりませんでした。もしかして:
コマンド'expr' -パッケージ 'coreutils' (main)
exprt: コマンドが見つかりません"
と表示されます。
(以前exportをexprtと打ち間違いをしてしまって、すぐ打ち直してその時は無事に通せたのですが…)
どうしたらこのエラーを消すことができますか?
おそらくこの方(https://teratail.com/questions/115514)と同じ症状なのですが、bashecなんてファイルが見つからず困っています。
bashrcのことでしょうか?
初心者ですみません、教えていただければ幸いです。
オフライン
lkdertyuj による投稿:
端末起動時、以前打ったコマンドのスペルミスを指摘するエラーが出ます。
「端末起動時」というのは「linuxのGUIでログインした後でデスクトップからターミナルを起動してその画面が開いた時」ということでしょうか?
それから、使われているshellはbashですよね?
ターミナルから次のコマンドを実行すれば、お使いのshellが分かります。
printenv | grep SHELL
以上のいずれも当方の想像通りだとした上で、更に「以前打ったコマンドのスペルミスを指摘するエラー」というのが過去に"export"を"exprt"と入力した時のものと同じだとすると、次の2点を確認したほうがいい思います。
a) historyに"exprt"と入力したのがコマンド実行履歴として残っているか?
b) ~/.bashrc に、history中の"exprt"に対応する履歴を再実行するような文が追加されていないか?
a)は、ターミナル上でhistoryコマンドを実行すれば分かります。下記のような出力が出ると思うのでその中に"exprt"が残ってないかを確認してください。
user@hostname:~$ history
1001 cd network/
1002 ls -la
1003 cd ../catalog/
:
b)は、~/.bashrc をless等で表示して調べればいいと思います。
historyの結果に"exprt"の履歴が残っていたなら、次のような"exprt"の全部または一部の前に"!"を付けた1文が ~/.bashrc の中に無いかを確認してください。
!exprt
!expr
!exp
:
"!xxxx"は、historyの履歴を新しいほうから探していって、xxxxの部分が一致した履歴を再実行します。
このような文が ~/.bashrc に紛れ込んでいたら、ターミナルを開いた時にもやはり再実行します。
コマンドの実行履歴であるhistoryは、端末起動中はメモリ上で管理されログアウト時にファイルに保存しログイン時にファイルから再度読み込まれます。
ですから、端末起動した時点でも過去のコマンド実行履歴は有効なままです。a)でhistoryに"exprt"の履歴が残ってないかを確認する必要があったのはそのためです。
以上のことをしてもよくわからないようであれば、1つターミナルを開いてから次のコマンドを実行してください。
bash -x -l
-x オプションは、bashスクリプトファイルの実行トレースを出力するものです。bashスクリプトファイルが指定されないと ~/.bashrc を実行します。
-l オプションは、~/.profileや、~/.bash_profile も読み込ませる(ログイン動作相当)指定です。
この2つのオブションで実行することで、 ~/.bashrc その他の一連のファイルを読み込んでbashが起動される状況をトレースすることが出来ます。
この出力結果から"exprt"が実行される箇所を特定することが出来るのではないでしょうか?
※上記のオプションで起動した後は-x オプションが有効になっているので、そのターミナルではbashの挙動についてコマンド一つ叩くだけでもトレースが出力されます。煩わしいので調べることが終わったらターミナルを閉じてしまってください。
以上です
オフライン
>>kznj
返信遅くなってしまいすみません。回答ありがとうございます。
hisoryにも~/.bashrcにもexprtは書いてありましたが、!はついていませんでした。
bash -x -lを試してみたところ、長々と出てきた中に
++ '[' -x /usr/lib/command-not-found ']'
++ /usr/lib/command-not-found -- exprt
コマンド 'exprt' は見つかりませんでした。もしかして:
コマンド 'expr' - パッケージ 'coreutils' (main)
exprt: コマンドが見つかりません
++ return 127
が見つかりました。libというところをいじればいいのでしょうか?
オフライン
kznj による投稿:
「端末起動時」というのは「linuxのGUIでログインした後でデスクトップからターミナルを起動してその画面が開いた時」ということでしょうか?
それから、使われているshellはbashですよね?
すみません言及するのを忘れていました。どちらもそのとおりです!
オフライン
lkdertyuj による投稿:
hisoryにも~/.bashrcにもexprtは書いてありましたが、!はついていませんでした。
!がついてないにしろ ~/.bashrc に紛れ込んだことは#2で推測してたとはいえびっくりしてます。
"bash -x -l"を実行していただいて新たにわかったこともあるのでその点を補足させていただきながら対処方法をお伝えします。
1) "/usr/lib/command-not-found"について
このファイルはpythonのスクリプトで、存在しないコマンドを実行しようとした時、単に「xxyyzz: コマンドが見つかりません」ではなく、下記のようにインストールパッケージをサジェストしてくれるものです。
コマンド 'exprt' は見つかりませんでした。もしかして:
コマンド 'expr' - パッケージ 'coreutils' (main)
exprt: コマンドが見つかりません
そして、Bashには検索パスにコマンドが見つからない場合,command_not_found_handle関数を呼び出すという仕組み が存在し、現行のubuntuではbashのこのcommand_not_found_handle関数にpythonスクリプトの "/usr/lib/command-not-found" を呼び出すように記述されています。
実際の記述は、/etc/bash.bashrc に書かれていて、ログイン時に /etc/profile を読み込んで行われる処理の中で、/etc/bash.bashrc も実行されてcommand_not_found_handle関数が有効になります。
以降は存在しないコマンドを実行しようとすると、command_not_found_handle関数 → "/usr/lib/command-not-found" の呼び出しが行われ、前述のインストールパッケージをサジェストするメッセージを表示しています。
詳しくは 第516回 command-not-found再発見 を参照しください。
#2の段階では、このpythonスクリプト"command-not-found"のことは当方の考えの中にありませんでした。
2) 対処方法について
lkdertyuj による投稿:
++ '[' -x /usr/lib/command-not-found ']'
++ /usr/lib/command-not-found -- exprt
コマンド 'exprt' は見つかりませんでした。もしかして:
コマンド 'expr' - パッケージ 'coreutils' (main)
exprt: コマンドが見つかりません
++ return 127
このトレースされた箇所は、実際には次のようになっていて(当方の環境のものを下記に引用)、1)で述べたように /etc/bash.bashrc に記述されているので、変更するべきではありません。
# if the command-not-found package is installed, use it if [ -x /usr/lib/command-not-found -o -x /usr/share/command-not-found/command-not-found ]; then function command_not_found_handle { # check because c-n-f could've been removed in the meantime if [ -x /usr/lib/command-not-found ]; then /usr/lib/command-not-found -- "$1" return $? elif [ -x /usr/share/command-not-found/command-not-found ]; then /usr/share/command-not-found/command-not-found -- "$1" return $? else printf "%s: command not found\n" "$1" >&2 return 127 fi } fi
従って、~/.bashrc にある"!"のついていないexprtが書かれた行を削除するか、exprtの前に"#"をつけてコメントにすればいいと思います。
実際、~/.bashrc にどんな感じで紛れ込んだのでしょうか?
~/.bashrc のファイル末尾への行追加されたようなら(リダイレクトの追加でくっつくとかも無いわけではないので)あまり気にせず単純削除でいいと思いますが、ファイルの中程に挿入されるように行が入っているのなら原因を特定しておいたほうが今後のためのような気がします。
~/.bashrc 全行でも構いませんし、該当行を含めて前後10行ずつくらいで抜粋したものとかでも、見せていただけるともう少しアドバイス出来るかも知れません。
以上です。
オフライン
詳しいお返事、本当にありがとうございます。
すみませんミスした経緯をお話していませんでした。
Anaconda3をダウンロードしたとき、bashrcのPATHにanaconda3の場所を追加するか聞かれた記憶がなかったので
username:~$ echo 'export PATH=/home/username/anaconda3/bin:$PATH'>> ~/.bashrc
(usernameはもちろん私のユーザー名です)とコマンドを打とうとして、exportをexprtと打ってしまったのです。(しかもいけたのかよくわからなくて正しいコマンドも何回も打ってしまった)だからbashrcに書き込まれたのだと思います。今思えばいらない作業だったような…
紛れ込んでいたのは、~/.bashrcの最後でした。
以下、その部分を載せます。(ユーザー名はusernameに変えてあります)
# >>> conda initialize >>> # !! Contents within this block are managed by 'conda init' !! __conda_setup="$('/home/username/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)" if [ $? -eq 0 ]; then eval "$__conda_setup" else if [ -f "/home/username/anaconda3/etc/profile.d/conda.sh" ]; then . "/home/username/anaconda3/etc/profile.d/conda.sh" else export PATH="/home/username/anaconda3/bin:$PATH" fi fi unset __conda_setup # <<< conda initialize <<< exprt PATH=/home/username/anaconda3/bin:$PATH export PATH=/home/username/anaconda3/bin:$PATH export PATH=/home/username/anaconda3/bin:$PATH export PATH=/home/username/anaconda3/bin:$PATH
これの最後の
exprt PATH=/home/username/anaconda3/bin:$PATH
export PATH=/home/username/anaconda3/bin:$PATH
export PATH=/home/username/anaconda3/bin:$PATH
の部分を消せばいいのでしょうか?私の理解不足、説明不足のせいでお手数おかけしてすみません…!
オフライン
もしかして最後の四行の上からして最後の四行は全部消しても差し支えないでしょうか?
オフライン
lkdertyuj による投稿:
これの最後の
exprt PATH=/home/username/anaconda3/bin:$PATH
export PATH=/home/username/anaconda3/bin:$PATH
export PATH=/home/username/anaconda3/bin:$PATH
の部分を消せばいいのでしょうか?私の理解不足、説明不足のせいでお手数おかけしてすみません…!
lkdertyuj による投稿:
もしかして最後の四行の上からして最後の四行は全部消しても差し支えないでしょうか?
コマンドとして存在しない"exprt"の行は消すとしても、残り3行を安易に消していいとは言えません。
ただ、3行とも同じ内容なので1行にするのは問題無いと思います。
というよりも、今の3行のままだと全部実行された後にPATHの値が
PATH=/home/username/anaconda3/bin:/home/username/anaconda3/bin:/home/username/anaconda3/bin:……
と、/home/username/anaconda3/bin が3つ重なってしまいます(でも悪影響はありません)ので、1行するのが無難かと思います。
その1行も消していいかは、"# >>> conda initialize >>>" 〜 "# <<< conda initialize <<<"のブロックの中(とそこから呼ばれる部分)で、"export PATH=/home/username/anaconda3/bin:$PATH"と同じことをしていないかで判断するべきなのですが、コードを追って確認するとちょっと手間がかかります。
ただ、もし同じことをしている箇所があると、前述の"export PATH=/home/username/anaconda3/bin:$PATH"が3行あったのと同じようにPATHの中で"/home/username/anaconda3/bin"が重複してしまいます。
ということなので、以下のように順を追って確認していけばよいかと思います。
1) exprtの行を消して、残りの3行を1行にして、その1行の先頭に"#"をつけてコメントにしておく。
2) 一旦ログアウトして再ログインし、存在しない"exprt"が原因のメッセージが出ないこと確認する。
3) "printenv PATH"を実行して環境変数PATHの内容を表示し、その中で"/home/username/anaconda3/bin"が重複していないかを確認する。
4) 重複がないなら、1)の"#"の行を消す(別に消さなくてよい)。
以上です。
オフライン
kznj による投稿:
1) exprtの行を消して、残りの3行を1行にして、その1行の先頭に"#"をつけてコメントにしておく。
2) 一旦ログアウトして再ログインし、存在しない"exprt"が原因のメッセージが出ないこと確認する。
3) "printenv PATH"を実行して環境変数PATHの内容を表示し、その中で"/home/username/anaconda3/bin"が重複していないかを確認する。
4) 重複がないなら、1)の"#"の行を消す(別に消さなくてよい)。
exprtのメッセージを消すことができました!ありがとうございます!
1)2)のあと、3)のprintenv PATHをやってみたところ、
/home/username/anaconda3/bin:/home/username/anaconda3/condabin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
と書いてありました。重複しているかと思いきやbin:とcondabin:と微妙に違ったので残したexport PATH=/home/username/anaconda3/bin:$PATHは消すべきではないのでしょうか?あ、でもコメントにしたのにここに/home/username/anaconda3/bin:があるということは重複してるということでしょうか…?
オフライン
今の状態で正しいと思います。
"#"を付けてコメントにした export PATH=/home/username/anaconda3/bin:$PATH の行は、環境変数PATHに"/home/username/anaconda3/bin"を追加する記述でした。
その行をコメントにした状態で一旦ログアウトして再ログインし(=~/.bashrcを最初から読み込みなおし)、printenv PATH を実行して環境変数PATHの状態を確認したら
lkdertyuj による投稿:
/home/username/anaconda3/bin:/home/username/anaconda3/condabin:/usr/loc
だったわけです。
コメントにした行がコメントになったことで実行されなくても、"/home/username/anaconda3/bin"は環境変数PATHに入ってますよね。
これは、例の"# >>> conda initialize >>>" 〜 "# <<< conda initialize <<<"のブロックの中(とそこから呼ばれる部分)で、環境変数PATHに"/home/username/anaconda3/bin"を追加してくれてるということです。
ですから、コメントにした行に書かれていた"export PATH=/home/username/anaconda3/bin:$PATH"は、実行する必要がない=コメントにしたままで構わない(なんなら行ごと削除してよい)ということです。
以上です。
オフライン
なるほど!理解できました。毎回の丁寧なお返事、本当にありがとうございました…!
オフライン