サクサク読めて、アプリ限定の機能も多数!
トップへ戻る
買ってよかったもの
qiita.com/ko1nksm
はじめに そりゃまあ 30 年も経てば古くなりますよ。「入門UNIXシェルプログラミング」は今もシェルスクリプトに関するオススメの本として名前が挙がる名著です。しかしこの本は古い本です。POSIX でシェルが標準化される以前の本で、内容から判断するとおそらく 1990 年ぐらいの常識に基づいて書かれています。 古いから参考にならないと言うつもりはありません。しかしどれだけ優れた本でも時間の流れには勝てません。良書であると思っているからこそ、古くなってしまった内容は訂正する必要があると考えています。なおシェルスクリプトに関する古い本はこれだけではありません。オライリーから出版されている本も古い本ばかりです。いつ頃に(原書が)書かれた本なのかを確認した方が良いでしょう。 ということでレビューというていで、古くなってしまった内容の訂正を行いたいと思います。新しく「入門UNIXシェルプログラミング
シェルスクリプトの関数の書き方 functionや()の本当の違いとは? 〜 あなたの知らないシェル関数の真実ShellScriptBashUNIXshellPOSIX はじめに シェルスクリプトの関数定義の方法は function や () を書くか省略するかの違いで三通りあります。これらは省略可能なだけで同じだと言われることが多いですがそれは本当なのでしょうか?それが本当ならなぜそのような書き方の違いが生まれたのでしょうか? 関数は Bourne シェルの開発者が重要だと考え最後に取り入れた構文です。関数を知らずしてシェルスクリプトを語ることは出来ません。シェルスクリプトが小さい場合は必要ないかもしれませんが、大きくなり後から読み返して何をやってるのかわからなくなる原因の一つは関数を正しく使っていないからです。この話についても詳しく書きたいのですが、今回のテーマではないので関数を使って
はじめに POSIX のコマンド一覧を見てやけに少ないなと思ったことはないでしょうか?例えば useradd がないのでユーザーが作れませんしcrontab はあるのに cron がないと中途半端です。重要なものがいくつも欠けおり、あれだけのコマンドでは到底 Unix を使うことができません。実は「Unix に実装すべき最低限の仕様」を定義した標準規格は他にありました。それが UNIX をこの世に生み出した AT&T 自身による標準規格 System V Interface Definition (SVID) です。この記事は POSIX に敗れて消えてしまったもう一つの UNIX 標準規格 SVID ・・・のコマンドの話です。(私の知識不足により C 言語インターフェースの話は含まれません。) SVID と POSIX の歴史 SVID は POSIX よりも早く標準規格を発表しています
はじめに シェルスクリプトの言語は他の言語と反対で 0 が真で 1(0以外)が偽であるという「間違った説明」をよく目にします。シェル言語も他の言語と同じで 0 は偽で 0 以外が真です。他の言語と真偽値の意味が「逆ではない」ので混同しないようにしてください。 間違ったシェルスクリプトの説明を JavaScript に置き換えるとこのようになります。 if (exit_status == 0) { // exit_status が 0 ならこちらが出力されるから JavaScript では 0 が真である console.log("true"); } else { console.log("false") }
なぜシェルスクリプトで高度なデータ管理にSQLiteを使うべきなのか? ~ UNIX/POSIXコマンドの欠点をSQLで解決するShellScriptUNIXSQLitePOSIXQiitadelika 「利用者は数十億人!? SQLiteはどこが凄いデータベース管理システムなのか調べてみた」の続きです。 はじめに 複雑な構造のデータを扱うのであればシェルスクリプトや Unix (POSIX) コマンドでデータ管理を行うのは避けるべきだと思います。解決不可能な問題が多いからです。しかしそれでも何かしらの理由でやろうと考える(やらなければいけない)のであれば SQLite を使うのをおすすめします。シェルスクリプトや Unix コマンドは行単位の単純なテキストデータをシーケンシャルにデータ処理するのが前提となっており、改行や空白が含まれるデータや複雑な構造のデータ扱うのは苦手です。またシェル
はじめに POSIX コマンドはどの環境にもある(追加インストールの必要がない)コマンドだと思われがちですがこれは間違いです。POSIX コマンドにどの環境にもあるという性質は有りません。POSIX コマンドの中でどの環境にもあるコマンドは実際には半分程度しかありません。 関連記事 POSIX準拠 とは本当はどういうことなのか?「POSIXで規定されたものだけを使う」ではありません 補足 Linux は POSIX に準拠してないからだという意見もあるかとは思いますが、現実に使われている環境を無視して「どの環境にもある」と主張しても意味はありません。 本当にどの環境にもあるコマンドとは? 全 POSIX コマンドは 160 個 POSIX コマンドは全部で 160 個あります。そのうち 22 個はシェルにビルトインされているコマンドなのでどの環境にもあると言えます。残りは 138 個のコマ
POSIX 準拠とは 「POSIX準拠」とは移植性を高めるための POSIX が定義した要件を満たすことです。Linux/Unix用の多数のソフトウェアは POSIX に準拠しており、多くの環境での動作を実現しています。POSIX の要件には OS ベンダー向けとアプリケーションの開発者向けの要件があり、高い移植性の実現には双方が POSIX の要件を満たして開発する必要があります。POSIX が目標とする移植性とは実行ファイルのバイナリがそのまま動くことではなく「ソースコードレベルの移植性」です。つまり 「アプリケーションの移植性が高い」とは別の環境でのビルドとインストールが容易であるという意味です。例えば cURL、SQLite、bash などは POSIX 準拠のソフトウェアの例で、数多くの OS で動作しているという事実は POSIX 準拠であることの証明です。現在、数えきれないほ
はじめに 知っての通り NoSQL とは一般的には RDBMS ではないデータベース管理システムのことですが、実は 世界初の「NoSQL」は Unix シェルベースの RDBMS なのです。NoSQL は Unix 哲学に基づいており、標準入出力やパイプを使うフィルタコマンドや、SQL の JOIN や集合演算相当の機能を持ったコマンドセットとなっており、シェルスクリプトや awk や Perl で実装されており、データはすべてプレーンなテキストファイルに保存します。 それが「NoSQL: a non-SQL RDBMS」です。 注意 この記事は技術系の読み物(雑学)です。データベースの技術的な話はほとんど出てこないのであしからず。 ネタバレ この NoSQL が誕生したのは 1998 年です。そして、みんなが知ってる NoSQL という言葉が誕生したのは 2009 年です。そういうことで
はじめに SQLite は世界で一番使われている だから世界で一番凄いものに決まってるだろ SQLite は世界で最も使われている RDBMS です。名前に反して(?)おもちゃの RDBMS ではありません。元ネタと同じで 一番普及しているからと言って必ずしも一番凄いものであるとは限りませんが、普及しているのであればそこには何かしらの理由があるはずです。その理由を調べないことには、凄いか凄くないかの結論は出せないので SQLite のなにがそんなに凄いのかを調査しました。 2022/04/01 続編記事↓を書きました。 注意 この記事は「なぜシェルスクリプトで高度なデータ管理にSQLiteを使うべきなのか? ~ UNIX/POSIXコマンドの欠点をSQLで解決する」の補足記事して書いたものです。ところどころ不自然にシェルスクリプトや Unix コマンドの話が登場するのはそのためです。基本的
Mac を遅くしている ReportCrash を停止する方法 ~ Chrome が固まる原因かも!?MacMacOSXReportCrash 最近 Mac (macOS Big Sur) が妙に重くなっていて「アクティビティモニタ」(ユーザーガイド)を見たら ReportCrash が大量に CPU を消費していました。本当の原因(人によって原因は様々でしょう)は Chrome 関連のコンポーネント1のようでしたが、実害をもたらしている張本人は ReportCrash なのでこれを停止しました。この方法は man ReportCrash (参考)に書いてあるので公式の方法と考えて良いでしょう。 ReportCrash を停止させる方法 「ターミナル」アプリを起動(詳細)して以下の二つのコマンドを実行するだけです。 (⏎ は enter キー。sudo ~ の行を実行するとログインパスワー
はじめに コマンドの出力をパイプ + while read ループで処理した時にループの中の変数がループの外で使えない(変数の中身が空になっている)という問題の解決方法の紹介です。これも何番煎じかのネタだと思いますが、良くない解決方法が目につき、あまり紹介されてないテクニックもあるので、それらの情報をすべてまとめ、何がどういう理由で駄目なのか?良い方法とはなにか?を解説するのがこの記事の趣旨です。推奨 5 パターン(+非推奨 3 パターン)の解決方法を解説しています。 パイプ・サブシェル問題とは? 以下のような問題です。 #!/bin/sh total=0 seq 10 | while IFS= read -r line; do echo "$line" total=$((total + line)) done echo "$total" # 1 + 2 + ... + 10 = 55 と
はじめに シェルスクリプトはコマンドをパイプでつなぐだけで簡単にパイプライン並列化を行うことが出来ますが、効率よく並列処理を行えるかどうかは別の話です。ボトルネックやオーバーヘッドがあるので単純にパイプでいくつもコマンドをつないでいくだけで簡単にどこまでも効率よく並列処理が行われるなんて事は技術的にありえません。そんなに簡単なら他の言語でも採用しているはずです。この記事ではシェルスクリプトで「何も考えずに」パイプでコマンドを多数つなげるスタイルが CPU 性能を効率よく使う上でのアンチパターンであることを示し、パイプで CPU を効率的に使ってパフォーマンスをあげたい人が知らなければいけないパイプライン並列化の重要な基礎知識とtime コマンドの読み方を解説します。 コマンドをパイプでつないで並列処理を行うパイプライン並列化は簡単に使えますが、並列処理の手法の中でおそらくもっとも制御が難し
はじめに シェル芸は可読性が低いです。シェルスクリプトで使うべき書き方ではありません。(そもそもシェル芸はシェルスクリプトで使うものではなかったはずですが?)この記事はこのことをはっきりと伝えるために書きました。 シェル芸とは「主に UNIX 系オペレーティングシステムにおいてマウスも使わず、ソースコードも残さず、GUI ツールを立ち上げる間もなく、あらゆる調査・計算・テキスト処理を CLI 端末へのコマンド入力一撃で終わらせること」らしいです。一般的にはワンライナーのことですね。詳細は他の記事に丸投げします。 シェル芸 | 上田隆一の仕事とか 【シェル芸人への道】シェル芸人の第一歩 シェル芸とシェルスクリプトの大きな違いは可読性とメンテナンス性の有無です。シェル芸は可読性やメンテナンス性やその他もろもろをガン無視し、一行でやってみせようという「芸」です(個人的な感想です)。念の為ですが一
重要 2022-01-30 追記 この記事で解説していた警告の出力は 2022-01-21 に取り消されました(参照 Revert deprecation of which)。そのため Debian which が GNU which に変わることは(少なくとも近い未来では)ないと思います。しかしながら which を使うよりは POSIX で規定されている command と type を使う方を推奨します。 はじめに which コマンドはシステムにインストールされてるとは限りません。実際に最小構成でインストールされてない環境として CentOS があります。一方 command -v は POSIX 規定されているので POSIX に準拠したどのシェルでも問題なく使えます。シェル上では which コマンドを使っても良いと思いますが、シェルスクリプトでは command -v を使う
はじめに この記事は正しく理解してないとハマりやすい set -e を正しく使う方法を解説しています。実はこの記事は前に書いた「シェルスクリプトのset -eを罠を避けて使う方法」の簡略版で前回は実際の動作を詳しく書いたのですが、内容がうまくまとまらなくて満足しておらず、私が set -e を使う時に気をつけてることを考えるともっとシンプルだよなということで新たに書き直すことにしました。普通に set -e を使うだけならこの記事の範囲の理解で十分だと思います。詳しい挙動については前回の記事を参照して下さい。 2021-12-16 「4. set -e の効果がコマンド置換に継承しないシェル対策」を追加 set -e とはなにか? この記事を読むような人は知っているかと思いますが set -e とはコマンドの実行結果がエラー(= 終了ステータスが 0 以外)になった時にシェルスクリプトを自
シェルスクリプトは変数代入で = の前後にスペースを置けない!・・・の本当の理由を知ると優れた文法が見えてくるShellScriptBashUNIXshellPOSIX はじめに シェルスクリプトの変数代入で = の前後にスペースを置くことができない理由は、検索すれば「プログラマーの君! 勘違いするな! シェルスクリプトでは読みやすさのためにスペースを置くな!! という話」のような記事がすぐに見つかります。記事に書いてあるとおり変数代入とコマンド呼び出しと区別がつかないからです。それは間違いではないんですが、私はもう少し説明が足りないと感じています。そこで今回は = の前後にスペースを置けない本当の理由を解説したいと思います。 の前に皆さんにはこの話を読みながら、自分がシェルスクリプトの言語設計者だったとしたら、どういう言語仕様にするかを考えて欲しいです。なぜかと言うとシェルスクリプトの文
シェルスクリプトで正規表現の照合シンボル[.string.]と等価クラス[=char=]と文字クラス[:classname:]を正しく使う方法ShellScriptBash正規表現POSIX はじめに POSIX で標準化されている正規表現の 照合シンボル [.string.]、等価クラス [=char=]、文字クラス [:classname:] の正しい意味と使い方です。検証は主に Debian 上で行っています。シェルスクリプト(コマンド)で動作確認していますが、本質的にはロケールの話なので各プログラミング言語にも当てはまるのではないかと思います。 参考記事 シェルスクリプトの正規表現の詳細解説(令和最新版) 注意 これらの表記が使えないと思ったら これらはすべてブラケット表現 [] の中で使う特殊な文字を意味する表記です。念の為ですがブラケットが 2 重になっているわけではありません
「え?UNIXなのにPOSIXに準拠してないの!?」シェルスクリプト実行環境をPOSIX準拠モードに変更して互換性を上げる方法 (Solaris, AIX, HP-UX, Linux, macOS, BSD) ShellScriptUNIXSolarisAIX はじめに POSIX の認証 または Unix の認証 を取得していれば POSIX に準拠している。そう思ってはいないでしょうか? たしかにそのとおりです。POSIX に準拠しています。ただしデフォルト状態で POSIX に準拠しているとは限りませんです。特に歴史が長い商用 Unix では過去にリリースしたバージョンとの互換性を重視して歴史的な Unix = System V 互換の動作である「互換モード」がデフォルトになっていることが多く「POSIX 準拠モード」にはなっていません。(注意 「互換モード」「POSIX 準拠モード
はじめに POSIX とは Portable Operating System Interface の略で 主に Unix 系 OS でソフトウェアの高い互換性(移植性)を実現するために、OS との C 言語用アプリケーションプログラミングインターフェース(API)と共に、シェルとコマンド(ユーティリティ)の仕様を定めた標準規格です。現在一番支持されている標準規格ですが、いきなり POSIX が生まれたわけではなく、さまざまな紆余曲折があって現在の形に落ち着きました。この記事では POSIX をメインに関連する標準規格とその歴史をまとめています。 補足 表記の揺れに注意。IEEE (Std) 1003 は POSIX のことです。1003 が POSIX を意味する番号ですが、省略されたりされなかったりします。 注意 標準規格がいくつもあり標準化団体が変わったりと複雑すぎるのでいろいろと間
シェルスクリプトのデータ出力タイミングが遅い? それはパイプ通信に起因するバッファリングが原因かもという話ShellScriptBashPOSIX はじめに この記事は「実践!ポータブルシェルスクリプト 〜 シェル関数によるLinuxとmacOSの移植性・互換性問題の攻略方法」の派生記事です。タイトルが長いのでこの記事では「前回の記事」と呼ぶことにします。 前回の記事では、バッファリングによってデータが遅延する問題を解決するためのコマンドの使い方が、Linux (GNU) と macOS (BSD) で異なるため、それをどうやって解決するかという話をしました。この記事は前回と異なる話で、この現象がパイプ通信によって引き起こされる問題であるため、出力タイミングが重要ならパイプ通信を使ってはいけない、そしてリアルタイム的な処理が必要なソフトウェアはシェルスクリプトで作るべきではないという話をし
補足 GNU tar のメジャーリリース は 1.14 (2004-05) 最初の tar コマンドの登場は 1979 年で Version 7 Unix で初めて実装されました。Version 7 Unix のマニュアル には tar コマンドがあります(ちなみに cpio コマンドはありません)。この時の形式が GNU tar では v7 形式と呼ばれています。 POSIX 1003.1-1988 で tar 形式を拡張した ustar 形式が登場します。最大のファイル名の文字数は増えていますが、最大ファイルサイズが 8GB であるという制限がありました。この ustar 形式は POSIX.2 で登場した pax コマンドで扱うことができます。(上記の表は ustar "形式" が登場した時期を書いていることに注意してください) GNU tar の開発が開始されたのはおそらく 199
はじめに シェルスクリプトに関しての長所と短所をまとめてみました。多くの短所を上げていますが、私はシェルスクリプトを嫌っているわけではなく(むしろ逆)、現在のシェルスクリプトが抱える問題点を明らかにし、シェルスクリプトはどう使うべきか? またはどう使うべきではないか? 問題点があるならばそれを解決することはできないか? を考えるためにまとめています。問題を解決するにはまず問題点を明らかにしなければいけません。 またシェルスクリプトを本来の用途に合わないものに使うと逆に開発が難しくなってしまいます。それは使い方が悪いわけでシェルスクリプトの問題ではありません。間違った使い方によってシェルスクリプトの価値が不当に下げられてしまうことを減らすために、あえて多くの短所をあげています。つまり最初からこんな用途に使おうと思うな。ということです。(使うことを禁止はしませんが、わかった上でやりましょう。実
はじめに 「コマンド出力を変数に入れる」というのはコマンド置換 ret=$(cmd)(または ret=`cmd`)のことです。この機能の最大の罠は末尾の改行が全部消えてしまうことです。と個人的に思っているのですがあんまり話題にならないですね。みんな知っていて気にしてないのか、単に気づいていないのか、わたし、気になります。さてこの記事ではコマンド置換の「末尾改行消失問題」と「その解決方法」ついて色々解説したいと思います。 末尾改行消失問題とは? 具体例で示したほうが簡単だと思います。改行を画面に沢山出力しようと思ったらどのようなコマンドを使いますか?echo? いや printf ですね。\n を繰り返すことで簡単に改行をいくつも出力できます。
POSIX 準拠のシェルスクリプトでは find | xargs よりも find -exec {} + を使うべき!ShellScriptBashshellPOSIX はじめに find の出力を xargs にパイプで渡すというのはよく見かける使い方ですが、find -print0 | xargs -0 が使えない POSIX 準拠のシェルスクリプトでは find -exec {} + を使った方が良いです。安全かつ十分に速いからです。よく見かける -exec {} ; ではなく -exec {} + ですので間違えないようにしてください。多くのケースでは + の方が優れているのですが ; ばっかり使われているのを見ると、意外と知られてない気がします。 少しだけ予備知識として、-exec {} ; は -exec {} \; と ; をバックスラッシュでエスケープするのがよく見る使い方
思いっきり雑学レベルの話ですみませんが、思い出した今書かないと忘れそうだなと思ったのでw この手法で何が出来るかと言うと、シェルスクリプトを実行するとスクリプトファイルの後ろ(exit で終了されて実行されない領域)に結合されたバイナリ形式の圧縮ファイル部分を抜き出して /tmp 以下に展開してそこに含まれているバイナリ形式の実行ファイルを実行して、一見シェルスクリプトのように見えるのに実はバイナリファイルを実行してるじゃんなどという楽しいことができます。いかにもハックまがいの手法に見えますが、どうやらこの手法は POSIX で考慮されているようです。 これを知ったのは「シバン shebang がないシェルスクリプトはどのシェルで動くかわからない(からちゃんと書いとけ)」の記事を書いている時に見つけた fish の PR 7802 です。fish はシバンがないスクリプトを実行するとエラー
はじめに getoptions はシェルスクリプト用のオプションパーサーです。getopts や getopt の代わりに使うことができ、getoptions をインストールするだけで簡単にシェルスクリプトのオプション解析を実装することができます。しかし、不特定の人に配布するシェルスクリプトの場合は getoptions をインストールしてもらうというのは選択肢にならないかもしれません。 でも大丈夫! getoptions はオプションパーサーのジェネレータとして使うこともできます。ジェネレータとして使うと自分でオプションパーサーのコードを書く必要はありません。 オプションパーサーとしての使い方はこちら 「シェルスクリプト(bash等)の引数解析が究極的に簡単になりました」 使い方 オプションパーサーとして使う場合は getoptions コマンドをインストールするだけで使えますが、ジェネ
すべての POSIX シェルで使用可能なので私はこれを推奨します。シェルスクリプトの改行コードは Windows の CR+LF ではなく LF を使用している前提です。いくつかの環境ではシェルスクリプトの改行コードに CR+LF を使用していても動くようなのですが(未調査)、遅かれ早かれ問題になるはずです。また需要は少ないと思いますが、POSIX シェル以前の Bourne シェルでも使える(おそらく)唯一の方法です。Solaris 10 などの古い環境にも対応させるのであればこの方法しかありません。 メリットはコードの量が最も少なく最も速いということです。デメリットは 2 行になるため少し不格好でインデントをする場合に困るだけですが、インデントに関してはこのような定数はスクリプトの上部の関数の外で定義するので通常は問題にならないはずです。 LF=$'\n' bash、ksh、mksh、
# Ubuntu 20.04 の bash での実行結果 # シェルから [ が何として見えているか $ type [ [ is a shell builtin # PATH から見つかる全ての [ コマンドを出力する # 補足 zsh では which がシェルビルトインコマンドで、シェルビルトイン版の [ も出力される $ which -a [ /usr/bin/[ /bin/[ $ type [[ [[ is a shell keyword # zsh では [[ をパターンとして認識してしまうのでダブルクォートが必要 $ type "[[" [[ is a reserved word ちなみに [ の外部コマンド版が /usr/bin/ と /bin/ の両方にあるのは Ubuntu 20.04 では /bin が /usr/bin へのシンボリックリンクになっているからです。Ub
Macでシェルスクリプトを書く人へ 「シェルはbashからzshに変わっていません!今でもbashで動くんだよ!」ShellScriptBashZshshell TL;DR Mac のシェルは macOS 10.15 Catalina で bash から zsh に変わったと一般に言われていますが、インストールされているシェルはバージョン番号の違いを除いて以前とほとんど変わっていません。 /bin/sh は POSIX モードで bash (/bin/bash) を起動します /bin/bash は bash 3.2.57 (正確には Apple 版 bash-123.40.1)です /bin/zsh は zsh 5.8 です その他に以下のシェルも標準でインストールされています。 /bin/csh, /bin/tcsh は tcsh 6.21.00 です /bin/ksh は ksh 9
次のページ
このページを最初にブックマークしてみませんか?
『@ko1nksmのマイページ - Qiita』の新着エントリーを見る
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く