- 投稿日:2021-12-05T23:39:43+09:00
【Linux】httpd.confのIncludeOptional
IncludeOptionalとIncludeの違い IncludeOptionalはIncludeと違い、指定したファイルやフォルダが存在しなくてもエラーを吐かない。 https://it-afi.com/apache/post-1372/
- 投稿日:2021-12-05T22:14:09+09:00
愛しの逆引きコマンド集【初心者・ズボラ向け】
この記事はエイチーム引越し侍 / エイチームコネクトの社員による、Ateam Hikkoshi samurai Inc.× Ateam Connect Inc. Advent Calendar 2021 6日目の記事です。 Webデザイナーの@ayumikが担当します。 好きな言葉は、「コスパ良い」と「120%改善」と「効率よいなぁ」と「定時退社」です。 前回のアドイベントカレンダーで下記の記事を書いてから、コマンドが愛おしくてたまりません。 というわけで、私の好きな言葉を全部叶えてくれる、逆引きコマンド集を公開します。 (もし他のおすすめやアドバイスなどあったら、コメント頂けると嬉しいです) 特定の文字列があるファイルを探して、その文字列の書き換えをしたいとき(grep,xargs,sed) 例えばある文字列を書き換えたいが、どこにどれだけ書かれているかわからないとき、サクッと対応できます。 grep -rl "置換前の文字列" ./検索したいディレクトリ ./ディレクトリは複数可能 | xargs sed -i -e 's/'置換前の文字列'/'置換後の文字列'/' grep あるファイル中の文字列に対して正規表現を利用して検索し表示する -r 指定するディレクトリを再帰的にgrep(検索)します。 再帰的とは? 指定したディレクトリ内の一つ一つに対して処理をする その際、その一つがディレクトリだったら、その 指定したディレクトリ内の一つ一つに対して処理をする その際、その一つがディレクトリだったら、その 指定したディレクトリ内の一つ一つに対して処理をする その際… となって、際限なく表記しなくてはなりません(そうせざるを得ないです)。 それだとキリが無くなってしまうので、普通は「再帰的に行う」と表現します。 http://blog.livedoor.jp/engineercollege/archives/46559976.html -l ファイル名のみ表示。 xargs あるコマンドを引数として、追加のコマンドを実行。 sed 指定したファイルをコマンドに従って処理し、標準出力へ出力。 -i 標準出力へ出力する代わりに、出力する内容で元のファイルを置き換える。 -e スクリプトを追加する。 特定の文字列が、どこに何箇所あるか検索(grep -c) いったん影響範囲がどのくらいでるか検索したいとき、便利です。 $ grep -rl "文字列" ./検索したいディレクトリ | xargs grep -c "文字列" ./検索したいディレクトリ grep -c マッチした行数を表示。 ファイル名をさくっと書き換え(find,rename) あまり、使い所ないかもしれませんが... ファイル名を一括で変更したいとき、一度訪れたので忘備録です。 find ./検索したいディレクトリ -name *検索前ファイル名(一部でも可)* -exec rename "検索前ファイル名(一部でも可)" "検索後ファイル名(一部でも可)" "{}" \; find ファイル検索 -name ファイル名で検索 -exec マッチしたパスにコマンドを実行 "{}" \ {}はマッチしたパスに置換されるプレースホルダーの役目をする記号で、マッチしたパスの回数だけchmodコマンドが実行される。 末尾の\によるエスケープが煩わしいが、;がシェルに解釈されないようにするために必要だ。 https://www.xmisao.com/2013/09/01/how-to-use-find-and-xargs.html rename 複数のファイル名を一括して変更 明日 Ateam Hikkoshi samurai Inc.× Ateam Connect Inc. Advent Calendar 2021 6日目の記事は、いかがでしたでしょうか。 明日は @nakagawa_shota さんが「ZoomとTeamsの画像認識に関する冬の自由研究について」書いてくれるようです。冬の自由研究、いいですね!お楽しみに!
- 投稿日:2021-12-05T22:10:22+09:00
バックグラウンドのSSH処理がジョブを停止させる問題
はじめに 背景 まず、こちらのコマンド実行ログをご覧ください。 SSHを絡めたコマンド実行のログ [angel@cent8-1 ~]$ ssh cent8-2 'echo I am $HOSTNAME' #<= パスワードレスな遠隔コマンド実行 I am cent8-2 [angel@cent8-1 ~]$ ./job.sh #<= 上記sshコマンドを組み込んだスクリプト Job start Remote operation start I am cent8-2 Remote operation end Job end [angel@cent8-1 ~]$ ./job.sh & #<= バックグラウンド実行すると…? [3] 2115 …(略) [3]+ 停止 ./job.sh 1つ目のSSHコマンドでは、パスワードレス ( 公開鍵認証等 ) での遠隔実行ができていることを確認しています。 2つ目では、そのSSHコマンドを組み込んだシェルスクリプトを実行しました。 ところが3つ目、自動化できる処理とみてバックグラウンド実行を行い、他の処理を行っていたところ、バックグラウンドで動作し続けるはずが「停止」となってしまいました。これはなぜでしょうか? ※厄介なことに停止は毎回必ずではなく、停止せずに処理を全うすることもままあります。 なお、スクリプトの内容は次にように、なんの変哲もないスクリプトです。 job.sh #!/bin/bash echo "Job start" sleep 10 echo "Remote operation start" ssh cent8-2 'echo I am $HOSTNAME' echo "Remote operation end" echo "Job end" ここに「停止」に至るような、どのような原因があったのでしょうか。 先に原因 ここで勘の良い人なら、「sshを組み込んだスクリプトでトラブル…、入力データを横取りしちゃうからじゃないの?」と気付くかもしれません。これは、ちょうど次のようなスクリプトで発生します。 SSHの入力データ横取りが問題になる例 while read LINE; do ssh USER@HOST 遠隔コマンド … done < input.txt この while read の構造を見ると、while文の入力リダイレクトで指定した input.txt の行数分ループを回す意図があると見られるものかと思います。 しかし実際は、ループ1回目のreadの後のsshが残りデータを大量に読み込んでしまうため、大抵の場合、次のreadでは読み込むべきデータが残っておらず、ループも1度で終了することになります。 ※このトラブルを避けるためには、sshの-nオプションを指定するなり、</dev/nullで明示的に入力元を切り替えることで、データの横取りを防ぎます。 今回の「ジョブ停止」に関しても、この「sshが入力を横取りする」と根が同じ話になっています。 ※ですので、直接的な解決策は、やはりsshの-nオプションや</dev/nullによる明示的な入力元の切り替えです。 環境 ということで、次からsshの挙動や停止の発生する過程に迫っていこうと思いますが。 今回はVirtualBox上のCentOS8で検証しています。が、どの環境でもそう大きくは変わらないと思います。 SSHの挙動 なぜ意外に感じたのか ということで、まずsshの挙動から見ていくことにします。 しかし、人によっては次のような疑問を持つかもしれません。 「sshが入力を横取りするなんて予め分かってることじゃないの?」「なんで経験もある人たちがそんなところで引っかかってるの?」 実は、多少慣れた人でもその感覚を裏切られる挙動が隠されています。その点をまず明らかにします。 ローカルでのコマンド実行 まず、ローカルでのコマンド実行ですが、LinuxというかUNIX系のシステムでは、次の図のように入出力経路が整えられるのが基本です。 よく俗に「標準入力はキーボード、標準出力は画面」と言われるのは、次のようなターミナルエミュレータからのシェルでの対話実行の状況を指しています。 しかしながら、入力が発生するのはあくまでそのプログラムがkernelに入力を要求するからであって、要求がなければ経路があるだけで使われません。 なので、シェルビルトインの echo、他にも多くのコマンドでは入力が発生しないはずなのです。 リモートでのコマンド実行 上で見たように、入力を要求しないアプリであれば入力は発生しません。であるならば、リモートで同様のアプリを実行しても入力は発生しないのでは?と考えるのが自然です。 しかし実際には、確かにリモートで入力は発生していないものの、SSHの途中の経路まで入力が発生しデータが運ばれます。 ※結果的にそのデータは使われず、事実上捨てられることになります。 このリモートで要求されてないはずなのに入力が発生するという状況が、内実を知らないと意外に感じられるポイントになると思います。 なぜ読み込みを行うのか ではなぜSSHでのリモートコマンド実行で読み込みが発生するか。それには、通信を経由する各アプリ ( sshコマンド、sshd ) も含め、全体での入出力経路を把握する必要があります。それが次の図になります。 ざっくり言うと、 ローカルでは標準入力・標準出力・標準エラーの複製が作られる。( 図中 in2~err2 ) リモートコマンドの標準入力・標準出力・標準エラーとはそれぞれ専用のパイプを通じてsshdがデータの入出力を行う ssh,sshd間はSSH通信により入出力データを中継する ということで、あたかもリモートコマンドがローカルで入出力してるかのような状況を作り出しています。 ※パイプを使うのは非対話の遠隔コマンド実行のためで、遠隔ログインとして対話的にシェルを起動する場合は代わりにPTYが使われます ここで、入力部分に着目します。 結果的には、ローカルの入力用ファイル ( 図中「ファイル(in)」 ) からリモートコマンドへデータが供給されるのですが、矢印は2つに分かれています。 これは、次のように処理が2系統に分かれているためです。 ssh~sshd の連携で行うのは、入力データのパイプへの蓄積 アプリが行うのはパイプからの入力 ( SSH通信を意識しない ) この2段階に分かれていることが、入力を行わないリモートコマンドの実行でも、ローカルで入力が発生する理由となります。 なぜならば、リモートで動作するアプリが要求するのはパイプからの入力であって、sshdへ直接データ要求を行うわけではありません。そうするとsshdはいつデータが必要になるか判断する方法がないのです。 結局、ssh~sshdの連携ではパイプへの入力がいつあっても良いように可能な限りデータを蓄積しておく動作が必要であって、リモートコマンドで入力を行わなくても、自発的にsshがデータ入力を行うことになる、ということです。 なぜ停止しないことがあるのか これで、入力を行わないリモートコマンドを実行する場合でも、sshが入力を発生させることが分かりました。 そして、まだ機構は詳らかにしていませんが、入力の発生 ( より正確には「kernelへの入力要求」 ) が、記事冒頭で紹介したジョブ停止につながっていることは分かっていることにします。 ではなぜ、停止するときとしないときがあるのか。そちらについても触れておきます。 この点に関して、結論は非常に単純です。sshは必ず入力を行うとは限らないから、です。つまり、入力を行えばジョブ停止が発生しますし、行わないなら発生しません。 そして、発生するかどうかの鍵はデータ有無を事前に問い合わせ、有るなら入力を行う、無いなら行わないという点にあります。 詳細は省きますが、この「問い合わせ」は、複数の入力経路を同時に扱う「多重I/O」のための典型的な手法です。 この図のように、対話シェルがTTY/PTYから入力データを取得し続けているような状況だと、SSHがデータ有無を問い合わせても「有り」となるとは限りません。これが「必ず入力を行うとは限らない」につながるわけです。 逆に、もし停止を確実に発生させたい場合、シェルがTTY/PTYからデータを吸い上げない状況を作れば簡単です。例えば以下のような手順です。 SSH遠隔コマンド実行を含むシェルスクリプトをバックグラウンド起動する sleepコマンドを適当な秒数指定で実行する sleepコマンド実行中にEnterキーを押す ※ここまでをSSHが起動される前に完了させる こうすることで、TTY/PTYには入力したEnterキー分のデータが、シェルから吸い上げられない状態で残っており、SSHは「データが残っている」TTY/PTYから入力を行おうとする、そしてジョブ停止を引き起こすということになります。 読み込みから停止につながる仕組み 前章では、( 入力が必要そうでない場面でも ) sshが入力を行う仕組みについて触れました。 ここからは、それがプロセスの停止につながる部分の話になります。 入力の競合という問題 冒頭で、「SSHが入力を横取りすることでトラブルになる例」を紹介しましたが、そのスクリプトを再掲します。 SSHの入力データ横取りが問題になる例(再掲) while read LINE; do ssh USER@HOST 遠隔コマンド … done < input.txt このスクリプトでは次の図のように、while でループを制御しているシェルが read コマンドで入力する分、起動されたsshが入力する分で、同じ input.txt からデータを取り合うことになります。 これはあくまでスクリプトを実装した人の問題であって、シェルやsshに責を問うのは筋違いです。 しかし、多数のプログラムが同時に入力を行いデータを取り合ってしまうと困る状況があります。それは、シェルからバックグラウンド実行により多重コマンド起動状態となっている状況です。 もしシェル、各コマンドがTTY/PTYから自由に入力することを許してしまうと大混乱が予想されます。シェルへのコマンド文字列のつもりが、実行中のコマンドへの入力として横取りされたり、あるいは特定のコマンドへ渡すつもりのデータが別のコマンドへ渡ってしまったり。 だからといって、それぞれのコマンドの入力を予め封じてしまうようだと、多重起動する便利さを目減りさせてしまうことになります。 実のところ、入力元が通常のファイルやパイプの場合への有効な手段はないのですが、対話用のTTY/PTYと連携する対策手段をLinuxやUNIX系OSで用意しています。 ジョブとプロセスグループ 上の「入力の競合」に対する解決策、それは起動するコマンドをジョブという単位で管理し、ただ一つのジョブにだけ入力を行う権利を与えるというものです。そのために用意されているOSの機構がプロセスグループです。 ※というか、「シェル上の『ジョブ』という管理単位」=「OS上の『プロセスグループ』」と思って構いません。 このプロセスグループに関して、OSの与える機能は次のものです。 シェルから生み出したプロセスの塊を「プロセスグループ」という単位で管理できる 間接的に生み出されたプロセス ( シェルにとっての孫 ) も割り当てられたプロセスグループを引き継ぐため、シェルスクリプト等、一連の処理のかたまりがグループ化される 別々のプロセスを同じプロセスグループにまとめることもできるので、command1 | command2 のようなパイプライン単位でグループ化できる シェルから生み出した中で、ただ1つのプロセスグループのみがTTY/PTYの入力権を得る このようなプロセスグループ(ジョブ)を「フォアグラウンド」と呼ぶ その他は「バックグラウンド」と呼び、入力権が得られない フォアグラウンドのジョブがない場合は、シェル自身がフォアグラウンドとなる ( コマンド文字列入力のために入力権を得る ) TTY/PTYのドライバレベルで入力権を制御する。 TTYのデバイス属性を扱うtty_ioctl(4)のTIOCSPGRPが該当します。 なお、プロセスグループを束ねる単位は「セッション」です。CUIログインするとTTY/PTYデバイスが割り当てられ、ログインシェルが起動し、そこからジョブを様々動作させられますが、この「ログインシェルを中心としたプロセス群」がセッションに相当します。 ジョブ管理者としてのシェルの役割は、フォアグラウンドジョブの停止や終了を検知してシェル自身をフォアグラウンドに引き戻したり、&なしで起動したジョブや、fgコマンドによって指定されたジョブをフォアグラウンドに設定することが挙げられます。 ところでプロセスグループやセッションは、プロセスIDと同様、数字で区別されており、ps コマンドで見ることができます。( -o での pgidやsidという項目が該当します ) 以下、実際に複数のジョブを起動し、そのプロセスグループの状況を出力させた例です。 プロセスグループの状況 [angel@cent8 ~]$ sleep 1000 & [1] 1567 [angel@cent8 ~]$ sleep 2000 & [2] 1568 [angel@cent8 ~]$ xargs -n 1 -P 0 sleep <<< "3001 3002 3003" & [3] 1569 [angel@cent8 ~]$ pstree -ap $$ bash,1356 ├─pstree,1575 -ap 1356 ├─sleep,1567 1000 ├─sleep,1568 2000 └─xargs,1569 -n 1 -P 0 sleep ├─sleep,1570 3001 ├─sleep,1571 3002 └─sleep,1572 3003 [angel@cent8 ~]$ ps -o pid,ppid,sid,pgid,args PID PPID SID PGID COMMAND 1356 1355 1356 1356 -bash 1567 1356 1356 1567 sleep 1000 1568 1356 1356 1568 sleep 2000 1569 1356 1356 1569 xargs -n 1 -P 0 sleep 1570 1569 1356 1569 sleep 3001 1571 1569 1356 1569 sleep 3002 1572 1569 1356 1569 sleep 3003 1576 1356 1356 1576 ps -o pid,ppid,sid,pgid,args [angel@cent8 ~]$ この例では、PID 1356のログインシェルを中心としたセッション1356が構成されていて、以下のような状況になっています。 ※この中心になっているシェルは「セッションリーダー」という扱いになります。 シェル自身 ( 暗黙のジョブ ) がプロセスグループ1356、フォアグラウンドでTTY/PTYからコマンド文字列を入力 sleep 1000 がプロセスグループ 1567 のジョブ %1 番 sleep 2000 がプロセスグループ 1568 のジョブ %2 番 xargsおよび、そこから起動された sleep 3001, 3002, 3003 がまとめてプロセスグループ1596のジョブ %3 番 なお、プロセスグループのことをシグナルをまとめて送れる単位ということでご存知の方もいるかも知れません。実際、コマンドとしての kill や、API(システムコール)としての kill はマイナスのPID値を指定することでプロセスグループに対するシグナル送信を行うことができます。 これは、kill %1のように、シェルのビルトインのkillコマンドで、ジョブ単位にシグナルを送るためにも活用されています。 制御端末とシグナル さて、上の「プロセスグループに対するTTY/PTYの入力権」の話ですが、これは全プロセスの中で特定のプロセス群にだけ許可を与えるという話とはちょっと違います。実際、ユーザレベルでのパーミッションが適切なら、全然無関係なプロセスがTTY/PTYから読み込んで入力データを横取りできてしまうからです。 この入力権の制御は、シェルがセッションを構成する時に、割り当てられたTTY/PTYを「制御端末」とすることで行っています。 以前「TTY/PTYに関するクイズ」という記事の「制御端末」の章で取り上げた「『紐づいているプロセスに何か働きかける』そのような対象となるTTY/PTYデバイス」ということです。 その記事でも話題に上げた通り、制御端末はTTY/PTYドライバからのシグナル送信と密接に関連しています。ざっと挙げると、 キーボード割込みをTTY/PTYドライバで解釈してフォアグラウンドジョブに対してシグナル送信を行う つまり、フォアグラウンド・バックグラウンドはPTY/TTYの入力権だけでなく、割り込みが発生する範囲の管理も担う 一般にCtrl-CはINTシグナルによるジョブ終了を引き起こす 一般にCtrl-ZはTSTPシグナルによるジョブ停止を引き起こす どの文字がどのシグナルに該当するかは、sttyコマンドで調整することができる TTY/PTYが回線切断扱いになった時の、セッションリーダーへのHUP(HangUP:回線切断)シグナル送信 セッションリーダーとなっているシェルは、このHUPシグナルを受けて、各ジョブにHUPシグナルを配る 「接続が切れても動作が途切れないようにnohupコマンドを」というのは、このHUPシグナル対策として習慣化されているもの。 ※nohup以外にも、disownによる管理対象からの切り離しや、setsidによるセッション分離等の対策がある バックグラウンドなプロセスグループからのPTY/TTYの入力に対する、TTINシグナルの送付 シグナルを受けたプロセスグループはTSTP等のシグナルと同じように、通常は停止される ※アプリ側で意図的に当該シグナルを無視したとしても、バックグラウンドだと入力権がないので、結局読み込みには失敗する シグナルで止められることによって、フォアグラウンドで復帰した時に、ちょうどPTY/TTYの入力処理から再開できるようになっている このシグナルの最後の項目で出てきましたが、冒頭の「シェルスクリプト内のsshによってジョブ自体が停止した」というのは、当にバックグラウンド状態のsshのTTY/PTY読み込みによるTTINシグナルによるものです。 このように、制御端末とシグナルとは密接な関係があるということです。 おわりに まとめ シェルスクリプト内のsshがジョブ停止を引き起こした原因は、sshがTTY/PTYに対して入力を行ったことによるもの リモートコマンドが入力を行わない場合も、ssh~sshd側はその判断ができないため、入力データがあれば入力処理を行い、sshdとリモートコマンドを繋ぐパイプに蓄積させる バックグラウンドのsshがTTY/PTYへ入力を行うことでジョブ停止になるのは、TTY/PTYドライバによるTTINシグナルによるもの TTY/PTYはフォアグラウンドジョブのみ入力権が得られるよう、キーボード割込みがフォアグラウンドジョブに限られるよう、OSで制御されている 所感 ということで、最近体験したssh入りスクリプトの停止にかこつけて、sshの入出力経路の話、ジョブ制御や制御端末の話を書いてみました。 なんの変哲もないCUI実行の裏側でも、ジョブを多重実行し制御するための工夫がつまっているということで、その一端に触れることができれば良いかなと思います。
- 投稿日:2021-12-05T20:10:30+09:00
LPIC 101 パーミッションの設定
LPIC1勉強の備忘録です。 アクセス権の変更 chmod オプション 説明 -R 指定したディレクトリにある全ファイルのアクセス権を変更する アクセス権限 対象 説明 u 所有者 g グループ o その他のユーザー a 全てのユーザー 操作 説明 + 権限を追加する - 権限を削除する = 権限を指定する 許可の種別 説明 r 読み取り許可 w 書き込み許可 x 実行許可 s SUIDもしくはSGID t ステッキービート SUID、SGID、ステッキービート 名称 アクセス表記 文字 説明 SUID 4000 u+s 指定したファイルは所有者のアクセス権限で実行できる SGID 2000 g+s 指定したファイルまたはディレクトリはグループのアクセス権限で実行できる ステッキービット 1000 o+t スティッキービットが設定されたディレクトリ以下のファイルとディレクトリは実際に設定したアクセス権に関係なく、所有者とrootユーザのみが名前の変更と削除を行えます。 デフォルトのアクセス権 umask ファイルやディレクトリを作成した時に設定されるアクセス権はumask値で決定されます。 ファイルは「666」ディレクトリは「777」からumask値を引いた値がデフォルトのアクセス権として適用されます。 umaskはユーザ毎に設定されています。オプションなしで実行すると現在のumask値を確認できます。 $ umask 0022 ファイルの所有者管理 chown ファイルやディレクトリの所有者を変更。 変更できるのはrootユーザーだけです。 オプション 説明 -R 指定したディレクトリとその中にある全ファイルの所有者を変更する # chown test:testgrp test.txt # chown test,testgrp test.txt //区切り文字は , でも指定可能 chgrp ファイルやディレクトリの所属するグループを変更。 一般ユーザでも使うことができるが、その際に変更できるグループは 実行ユーザーが所属するグループに限られます。 rootの場合はどのグループにでも変更することができます。 オプション 説明 -R 指定したディレクトリ とその中にある全ファイルの所有者を変更する 参考 あずき本
- 投稿日:2021-12-05T18:24:55+09:00
IOPSを取得する方法(Linux、iostatコマンド)
Linuxのiostatコマンドでメモリ使用率を取得する方法を紹介します。 環境 OS:CentOS Linux release 8.1.1911 実行結果 [root@centos8 ~]# cat /etc/redhat-release CentOS Linux release 8.1.1911 (Core) [root@centos8 ~]# 1. iostatコマンド iostatコマンドを実行すると、「CPU使用率の情報」と「I/Oデバイスの使用状況」が表示されます。 実行結果 [root@centos8 ~]# iostat Linux 4.18.0-147.8.1.el8_1.x86_64 (centos8) 2021年12月05日 _x86_64_ (1 CPU) avg-cpu: %user %nice %system %iowait %steal %idle 0.57 0.08 0.92 1.28 0.00 97.15 Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn sda 2.47 92.18 22.54 595320 145558 scd0 0.00 0.16 0.00 1040 0 dm-0 2.64 90.16 23.19 582271 149739 dm-1 0.02 0.34 0.00 2220 0 [root@centos8 ~]# -dオプションを付けてiostat -dを実行すると、「I/Oデバイスの使用状況」のみが表示されます。 実行結果 [root@centos8 ~]# iostat -d Linux 4.18.0-147.8.1.el8_1.x86_64 (centos8) 2021年12月05日 _x86_64_ (1 CPU) Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn sda 1.85 67.83 16.79 595336 147328 scd0 0.00 0.12 0.00 1040 0 dm-0 1.98 66.34 17.28 582287 151651 dm-1 0.01 0.25 0.00 2220 0 [root@centos8 ~]# -dオプションと'-x'オプションを付けてiostat -dxを実行すると、「拡張ディスク統計情報」が表示されます。 実行結果 [root@centos8 ~]# iostat -dx Linux 4.18.0-147.8.1.el8_1.x86_64 (centos8) 2021年12月05日 _x86_64_ (1 CPU) Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util sda 1.39 0.46 67.81 16.78 0.00 0.17 0.33 27.25 36.65 28.51 0.06 48.68 36.59 0.78 0.14 scd0 0.00 0.00 0.12 0.00 0.00 0.00 0.00 0.00 52.67 0.00 0.00 38.52 0.00 0.96 0.00 dm-0 1.35 0.63 66.33 17.27 0.00 0.00 0.00 0.00 37.08 26.32 0.07 49.01 27.45 0.71 0.14 dm-1 0.01 0.00 0.25 0.00 0.00 0.00 0.00 0.00 31.29 0.00 0.00 22.65 0.00 0.70 0.00 [root@centos8 ~]# 出力項目の内容については「LinuxのiostatコマンドでサーバーのI/Oデバイスの使用状況を確認する」を参照してください。 2. IOPSの値 ここでIOPS(Input/Output Per Second)(1秒間のI/O回数)は、 iostat -dコマンドの場合、「tps」の値 iostat -dxコマンドの場合、「r/s」+「w/s」の値 となります。 3. iostatコマンドの実行結果をファイルに出力 1秒間隔でiostat -dxコマンドの実行結果を表示させる場合、iostat -dx 1を実行します。 実行結果 [root@centos8 ~]# iostat -dx 1 Linux 4.18.0-147.8.1.el8_1.x86_64 (centos8) 2021年12月05日 _x86_64_ (1 CPU) Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util sda 1.30 0.43 63.30 15.70 0.00 0.16 0.33 27.04 36.65 28.23 0.06 48.68 36.14 0.78 0.13 scd0 0.00 0.00 0.11 0.00 0.00 0.00 0.00 0.00 52.67 0.00 0.00 38.52 0.00 0.96 0.00 dm-0 1.26 0.59 61.91 16.16 0.00 0.00 0.00 0.00 37.08 26.10 0.06 49.01 27.19 0.71 0.13 dm-1 0.01 0.00 0.24 0.00 0.00 0.00 0.00 0.00 31.29 0.00 0.00 22.65 0.00 0.70 0.00 Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 scd0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 dm-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 scd0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 dm-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 scd0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 dm-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 iostat -dxコマンドの実行結果に「時刻」を付けて表示させる場合、以下のコマンドを実行します。 iostat -dx 1 | awk '{ print strftime("%Y/%m/%d %H:%M:%S"), $0 }' 実行結果 [root@centos8 ~]# iostat -dx 1 | awk '{ print strftime("%Y/%m/%d %H:%M:%S"), $0 }' 2021/12/05 18:16:44 Linux 4.18.0-147.8.1.el8_1.x86_64 (centos8) 2021年12月05日 _x86_64_ (1 CPU) 2021/12/05 18:16:44 2021/12/05 18:16:44 Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util 2021/12/05 18:16:44 sda 1.28 0.43 62.48 15.50 0.00 0.16 0.33 27.01 36.65 28.20 0.06 48.68 36.08 0.78 0.13 2021/12/05 18:16:44 scd0 0.00 0.00 0.11 0.00 0.00 0.00 0.00 0.00 52.67 0.00 0.00 38.52 0.00 0.96 0.00 2021/12/05 18:16:44 dm-0 1.25 0.59 61.11 15.95 0.00 0.00 0.00 0.00 37.08 26.08 0.06 49.01 27.16 0.71 0.13 2021/12/05 18:16:44 dm-1 0.01 0.00 0.23 0.00 0.00 0.00 0.00 0.00 31.29 0.00 0.00 22.65 0.00 0.70 0.00 2021/12/05 18:16:44 2021/12/05 18:16:45 Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util 2021/12/05 18:16:45 sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2021/12/05 18:16:45 scd0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2021/12/05 18:16:45 dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2021/12/05 18:16:45 dm-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2021/12/05 18:16:45 2021/12/05 18:16:46 Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util 2021/12/05 18:16:46 sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2021/12/05 18:16:46 scd0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2021/12/05 18:16:46 dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2021/12/05 18:16:46 dm-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2021/12/05 18:16:46 2021/12/05 18:16:47 Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util 2021/12/05 18:16:47 sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2021/12/05 18:16:47 scd0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2021/12/05 18:16:47 dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2021/12/05 18:16:47 dm-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2021/12/05 18:16:47 ファイル(ここでは「iostat.log」)に出力する場合、以下のコマンドを実行します。 パイプをリフレッシュするためにsystem(":")を使用します。 iostat -dx 1 | awk '{ print strftime("%Y/%m/%d %H:%M:%S"), $0 } { system(":") }' > iostat.log 実行結果 [root@centos8 ~]# iostat -dx 1 | awk '{ print strftime("%Y/%m/%d %H:%M:%S"), $0 } { system(":") }' > iostat.log iostat.log [root@centos8 ~]# cat iostat.log 2021/12/05 18:18:50 Linux 4.18.0-147.8.1.el8_1.x86_64 (centos8) 2021年12月05日 _x86_64_ (1 CPU) 2021/12/05 18:18:50 2021/12/05 18:18:50 Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util 2021/12/05 18:18:50 sda 1.27 0.42 61.66 15.29 0.00 0.16 0.33 26.99 36.65 28.19 0.06 48.68 36.06 0.78 0.13 2021/12/05 18:18:50 scd0 0.00 0.00 0.11 0.00 0.00 0.00 0.00 0.00 52.67 0.00 0.00 38.52 0.00 0.96 0.00 2021/12/05 18:18:50 dm-0 1.23 0.58 60.31 15.74 0.00 0.00 0.00 0.00 37.08 26.08 0.06 49.01 27.15 0.71 0.13 2021/12/05 18:18:50 dm-1 0.01 0.00 0.23 0.00 0.00 0.00 0.00 0.00 31.29 0.00 0.00 22.65 0.00 0.70 0.00 2021/12/05 18:18:50 2021/12/05 18:18:51 Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util 2021/12/05 18:18:51 sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2021/12/05 18:18:51 scd0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2021/12/05 18:18:51 dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2021/12/05 18:18:51 dm-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2021/12/05 18:18:52 2021/12/05 18:18:52 Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util 2021/12/05 18:18:52 sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2021/12/05 18:18:52 scd0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2021/12/05 18:18:52 dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2021/12/05 18:18:52 dm-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2021/12/05 18:18:53 [root@centos8 ~]# 長時間、実行結果を取得する場合、バックグラウンドで動かして、ログアウトしても終了しないようにしたいこともあります。 その場合、nohupを使用して以下のコマンドを実行します。 nohup bash -c "iostat -dx 1 | awk '{print strftime(\"%y/%m/%d %H:%M:%S\"), \$0} { system(\":\") }'" < /dev/null > iostat.log 2>&1 & 実行結果 [root@centos8 ~]# nohup bash -c "iostat -dx 1 | awk '{print strftime(\"%y/%m/%d %H:%M:%S\"), \$0} { system(\":\") }'" < /dev/null > iostat.log 2>&1 & [1] 4054 [root@centos8 ~]# 出力ファイル名に時刻を持たせたい場合、以下のコマンドを実行します。 nohup bash -c "iostat -dx 1 | awk '{print strftime(\"%y/%m/%d %H:%M:%S\"), \$0} { system(\":\") }'" < /dev/null > iostat_$(date "+%Y%m%d_%H%M%S").log 2>&1 & 実行結果 [root@centos8 ~]# nohup bash -c "iostat -dx 1 | awk '{print strftime(\"%y/%m/%d %H:%M:%S\"), \$0} { system(\":\") }'" < /dev/null > iostat_$(date "+%Y%m%d_%H%M%S").log 2>&1 & [1] 4124 [root@centos8 ~]# ls iostat_* iostat_20211205_182259.log [root@centos8 ~]# 以上
- 投稿日:2021-12-05T08:29:55+09:00
wgetで失敗するトラブルシューティング
はじめに wgetコマンドでhttp経由でファイルを取得しようとしたところ、次のエラーがでて取得ができなかった。そのトラブルシューティング。 failed: Temporary failure in name resolution. wget: unable to resolve host address 環境 focal (Ubuntu 20.04) 前置き 結論をいうと、DNSによる名前解決ができなかったことが原因です。自分の環境で設定しているDNSサーバーでは名前解決ができないようで、代わりに、GoogleのPublic DNS(8.8.8.8)を設定すれば解決できた。 DNSサーバーのIPアドレスには、自分が契約をしているインターネットプロバイダーが公開しているDNSサーバーのアドレスを設定するのが普通だと思う。物理的な距離が一番近いため、そこのDNSサーバーで名前解決した方が一番高速だと思われるためだ。そもそも、インターネットプロバイダーと契約したとき、DNSサーバーのIPアドレスには、このIPアドレスを指定してくださいと、契約書に書かれているため、そのとおりに設定しているはずだ。自宅に外向けのDNSサーバーを構築して、そこで名前解決をさせない限り、以降、変更することはない。 それが、各プロバイダーのDNSサーバーを駆逐するかのごとく、GoogleがPublic DNSサーバーを公開しているのだ。 「GoogleのDNSサーバーってたぶんアメリカにあるんでしょ。そんなところまで 参照しにいったら、名前解決に時間がかかるじゃん」って思うだろう。だがどうも、GoogleのPublic DNSサーバーを参照した方が、レスポンスが速いらしい。詳細なベンチマークテストをおこなったわけではないので、どの程度高速になったかは分からない。少なくても体感的には高速度加減はわからない。 やったこと さて、実際に、GoogleのPublicDNSサーバーを設定してみよう。 DNSサーバーのIPアドレスは/etc/resolv.confで設定する。ls -l /etc/resolv.confをすると、/run/systemd/resolve/stub-resolv.confのシンボリックリンクとなっている。 resolv.confに次の一行を追加する。ルート権限でviを開かないと、保存ができないので注意。 nameserver 8.8.8.8 この後、wgetをすると、すんなりダウンロードができるようになりました。8.8.8.8はプライマリサーバーなので、セカンダリサーバーのIPアドレスも設定しておいた方が無難だろう。
- 投稿日:2021-12-05T01:45:53+09:00
初学者にlinuxのroot環境をオンラインで提供したので備忘録
きっかけ ローカルコミュニティの初学者の方々に少しでもlinuxに触れてほしいという思いから、今回の行動に至りました。 また、ただ環境を提供するだけでなく、初学者がCUI環境に入りやすいように、web上で、ホームディレクトリのファイル一覧を見たり、ホームディレクトリにファイルをアップロードできるようにしました。 やり方 dockerでubuntuコンテナを立ち上げ、そのコンテナをsshで公開するというのを人数分できるようにします。 準備 準備として、同一ディレクトリに以下の2ファイルを用意します Dockerfile FROM ubuntu:20.04 RUN apt-get update -y && \ apt-get install -y tzdata RUN apt-get install -y curl && \ apt-get install -y openssh-server && \ apt-get install -y vim RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config RUN curl -L https://github.com/sgreben/http-file-server/releases/download/1.6.1/http-file-server_1.6.1_linux_x86_64.tar.gz | tar xz COPY start.sh / ENTRYPOINT ["/start.sh"] RUN sed....の部分で、rootアカウントにsshでログインするために、設定ファイルを書き換えています また、その下で、web上でファイルを閲覧・アップロードするためのツールをダウンロード・展開しています。 sh'start.sh #!/bin/sh echo root:$PASSWORD | chpasswd service ssh start ./http-file-server -uploads -q -r redirect /$WEB_ROOTER_PATH=/root exec tail -f /dev/null start.shではrootユーザーのパスワードの変更、sshの起動、http file serverの起動をしています。 一番下のコマンドについてはこちらを参考にさせていただきました↓ https://www.itmedia.co.jp/enterprise/articles/1602/17/news004.html ビルド 先ほどのディレクトリで以下のコマンドを実行します。 docker build -t serve . これで、serveイメージの完成です。 実際に動かす 実際に動かすには、上記で作ったイメージを利用したコンテナを人数分作らなければなりません。 その際、注意するのはポートフォワーディングのポートが被らないようにすることです。 また、ユーザーのホームディレクトリを安易に見られないように、WEB_ROOTER_PATHを十分ランダムなものに設定する必要があります。 理想としては、ホスト側でwebサーバーを前にかませて認証を設けるのが良いでしょう。 今回は一人に提供する前提のコンテナ化コマンドを記載します。 docker run -it -p 7000:22 -p 8000:8080 -e PASSWORD=1234 -e WEB_ROOTER_PATH=test -d --name servetest serve ※ 7000:22はsshのポートフォワーディング、8000:8080はhttp file serverのポートフォワーディングです。 ここまでくれば、あとはsshでlinux環境に入れますし、webからディレクトリを参照することもできます。 ※実際に複数人数分のコンテナを作る際は、7000、8000の部分をそれぞれ被らないように変更して、人数分のコンテナを作成します。また、必要に応じてsshでログインする際のPASSWORDも変更しましょう。※ ssh接続の例(host ipがlocalhostの場合) ssh -p 7000 root@localhost web接続の例(host ipがlocalhostの場合) http://localhost:8000/test --追記: ROOTERを設定したところで、リダイレクトされるので意味ないですね.....どうしましょう... 2021 12/5追記: -rオプションでリダイレクト先を存在しないディレクトリ(/redirect)にすることでとりあえず回避しました。 繰り返しになりますが、理想は直アクセスの前に認証を挟むのが良いです。 終わり とりあえずlinuxに気軽に触れてほしいという衝動で作成したので荒い部分もあると思いますが、おおむね満足のいくものができたのでよかったです。普通にOpenStack使うという手もありますが、諸事情で数日中に提供準備を整えたかったので、使用したことのあるdockerで構築しました。