サクサク読めて、アプリ限定の機能も多数!
トップへ戻る
ノーベル賞
qiita.com/ko1nksm
はじめに シェルにはサブシェルという重要で独特な概念があります。どの言語でも独特の概念はあるものですが、シェルにとってはそれがサブシェルです。豆知識やうんちくとかいうレベルではなくサブシェルは基礎知識なので、シェルスクリプトをちゃんと書こうという人は知らなければヤバいと言っても過言ではありません。「難しい概念だから知らなくてもいいよ」などではなく、サブシェルを理解しなければまともに動くシェルスクリプトを書くことはできないと思ってください。独特なだけで難しいわけではないのですが、ちゃんと正しく説明できているものは市販の技術書を含めてもあまりありません。 サブシェルを一言で言うと、
ちなみに Space Travel にスコア機能やゲームのなにかを記録する機能はありません。描画は点と線だけで画像ファイルの読み込みなどは行いません。オリジナルの Space Travel は紙テープから起動してオンメモリで動くはずです。何が言いたいかというと Space Travel を動かすためにファイルシステムを作る理由はないということです。紙テープからの起動なんて時間がかかるのでは? と思ったあなたは鋭い。1980 年頃の音楽用のカセットテープをコンピュータの記憶媒体として使っていた時代では、実際にゲームを始める前のロード時間に何分も待っていました。 初期の Unix 開発の技術は Space Travel から学んだ さて、この記事は Space Travel を通して Unix 開発の初期の歴史や、なぜケン・トンプソンは Unix を開発するに至ったのかを知ろうというのが趣旨の
いい加減シェルスクリプトで [ $? -eq 0 ] や [ $? -ne 0 ] なんて エラー処理を書くのはやめよう!ShellScriptBashLinuxUNIXmacOS はじめに [ $? -eq 0 ] や [ $? -ne 0 ] は冗長でデメリットしかありません。非常に多く見かける書き方ですが、1979 年に Bourne シェルが広く公開された時からこのようなコードは必要ありませんでした。実際に当時はこのような書き方は使われておらず、このような書き方をしなければならなかった歴史的な経緯などはありません。これはなぜか広まってしまった良くない書き方です。 優れたコードとは無駄がないシンプルなコードです。丁寧なコードとは無駄な処理を書くことではありません。[ $? -eq 0 ] や [ $? -ne 0 ] は書かないほうが、簡単で読みやすくわかりやすくなります。優れた文法
補足1: 上記以降のその他のシェルの歴史 ksh: 1980年頃に開発開始し、1983年に ksh83 がリリース、ksh93 は大幅強化版 bash: 1988年1月に開発開始し、1989年6月に 0.99 がリリース pdksh:1987年から1989年頃に開発、その派生版 (mksh) を OpenBSD が採用 ash: 1989年5月にリリース、その派生版をFreeBSD、NetBSD、Debian系Linux などが採用 zsh: 1990年頃に1.0がリリース その他のシェル シェルの歴史 総まとめ(種類と系統図)と POSIX の役割 〜 シェルスクリプトの現在・過去・未来 補足2: POSIX 標準化以降 1992 年に POSIX によってシェルの仕様が標準化されました。しかし Bourne シェルは POSIX に準拠することなく 1992 年の SVR4.2 版を最
はじめに $\color{#e02020}{\huge{\bf{それは単なる「POSIX標準規格書の用語集」じゃい!}}}$ ということで、まことしやかに POSIX がテキストファイルの仕様を決めているかのような噂が流れていますが(私も言ったことがあるかも?)、POSIX に「テキストファイルは末尾に改行を書かなければならない」なんて仕様はありません。また POSIX は「テキストファイルの末尾を改行にすべし」などとも言っていません。POSIX は「3. Definitions(定義)」で 「POSIX 標準規格書の中で使用している『テキストファイル』という用語の正確な意味は・・・である」と言っているだけなんです。用語の意味を定義しただけであることも、ちゃんと POSIX に書かれています。 ❌️ POSIXはテキストファイルの末尾に改行を書かなければならないと決めた ⭕ POSIXでは
はじめに grep コマンドや sed コマンドの -e オプションや -E オプションの意味を勘違いしている例を見かけるので訂正です。 -e オプションは正規表現またはスクリプトを追加指定するためのオプションです -E オプションは拡張正規表現モードを有効にするためのオプションです -e と -E は反対の意味を持つオプションではありません。まったく異なる機能を提供しているオプションです。-e オプションは拡張正規表現でも使うことができます。 -e オプションは正規表現またはスクリプトの追加指定 まず、なぜ -e オプションというものが作られたのか? それはハイフンで始まる正規表現を指定したり、sed スクリプトを組み立てたりするためです。 grep コマンドの話 例えば grep コマンドで -a という文字列を検索したい場合はどうするでしょうか?
はじめに CUI は英語圏では通用しないようです。CLI という正しい用語を使いましょう。というか CUI のことしか書いていない初心者向け記事、量産させすぎ😡 ❌ CUI (キャラクターユーザーインターフェース)なんて言葉は英語にはありません 🟢 CLI (コマンドラインインターフェース)が正しい用語です 🟢 GUI (グラフィカルユーザーインターフェース)も正しい用語です なんども繰り返されている話題ですが、ふと書きたくなったので書きます。 CLI (コマンドラインインターフェース)ってなに? CLI とはその名の通り、コマンドラインを使ったインターフェースのことです。つまり一般的にはシェルを使うユーザーインターフェースです。よく見るコレ↓です。 $ ls bin dev home lib64 mnt proc run srv tmp var boot etc lib media
Twitterとか見て「そうだったのかー」とか言うんじゃなくて、ちゃんと調べてみましょうよ。/usr は元々ユーザーのホームディレクトリをおいていた場所ですよ。/bin などを置いていたシステムディスクの容量が足りなくなったので別ディスクだった /usr 以下を使うようになっただけです。Unix System Resources とかそんな長い名前、後付けに決まってるでしょ? 翻訳は面倒なので、DeepL(の少し手直し)です。 初期の Unix のドキュメントから URLと1972年という年から、おそらく Version 1 Unix (1971) のドキュメントだと思います。ここ 経由で見つけました。 12ページにこのようなものがあります。詳細はよくわかりませんがディレクトリ構造でしょう。 idata: / root 41. 140016 .byte 7,1 9f-.-2 41. <..
はじめに: データが途切れる問題 dd コマンドでパイプから dd bs=サイズ count=1 でデータを読み取ると途中で途切れることがあります。知っている人にとっては有名な問題だと思いますが。 $ seq -f '%0999g' 100 | dd bs=100000 count=1 | wc -l 0+1 records in 0+1 records out 49152 bytes (49 kB, 48 KiB) copied, 5.0325e-05 s, 977 MB/s 49 $ seq -f '%0999g' 100 | dd bs=100000 count=1 | wc -l 0+1 records in 0+1 records out 4096 bytes (4.1 kB, 4.0 KiB) copied, 0.000208169 s, 19.7 MB/s 4
FreeBSD では 2024-05-31 に 200112 から 200809 への変更がようやく行われました(一度間違えて 200808 と書いてしまっていますが)。 https://cgit.freebsd.org/src/commit/?id=2e30926a68 https://cgit.freebsd.org/src/commit/?id=6e0278408e macOS は FreeBSD のユーザーランドのコマンドを使用しているため、そのせいで 200112 のままだった可能性も考えられますが、シェルやカーネルは FreeBSD のものではないため、FreeBSD が変更になったからと言って macOS が更新されるとは限らないでしょう。Solaris 10 と 11 ではディレクトリごとに準拠バージョンが異なるバイナリが配置されており以下のようになります。Solaris
期待してる人ががっかりしないように、最初に結論を書いておくと dash、busybox (ash)、mksh、yash、zshにおいて読み込み速度は大幅に速くなりますが bash においては変わりません。ただしは使用メモリが減ります。kshは少し速くなりますが逆に使用メモリは大幅に増えます。シェルスクリプトでの読み込み速度を上げるもので、他の言語を使ったりコマンドを呼び出すよりも速くなるわけではありません。 シェルスクリプトでファイルを一行ごとに読み込む時、一般に使われているのは read 関数です。ですが、この read 関数、遅いというわさを聞きました。たしかに一行毎ずつ読み込むのですから cat を使ってファイル全体を読み込むのに比べれば遅いでしょうが、そのままでは一行ずつ処理をすることは出来ません。 さて一行ずつ処理したい場合に使えるのは read 以外どのような方法があるでしょう
はじめに Unix 哲学には DOTADIW: Do One Thing and Do It Well という言葉があります。日本語に訳すと「一つのことをうまくやる」となりますが、しばしば単機能のコマンドを作ることだと勘違いされています。もし勘違いしている人がいるのであれば、ぜひその人に聞いてみてください。なぜ grep コマンドはマッチした行数をカウントする機能を昔から持っているのですかと。昔からある wc コマンドがあれば grep コマンドに行数をカウントする機能をもたせる必要はないのではないかと。 -c Only a count of matching lines is printed. wc provides a count of the words, text lines, and roffcontrol lines for each argument file. 複数の機能を
Unix 哲学的に考えれば、行を並び替える sort コマンドと重複行を取り除く uniq コマンドは別のコマンドであるべきなように思えます。しかし sort コマンドには -u オプションとして uniq コマンドに相当する機能が組み込まれています。なぜそうなっている(そうなってしまった)のかを「ソフトウェア作法(さくほう)」を参照しながらこの記事で明らかにしたいと思います。 関連記事 Unix哲学「一つのことをうまくやる」は単機能のコマンドを作ることではない 「誰」がuniq機能をsortコマンドに組み込んだ!? 熱烈的な Unix 哲学の信者は「どうせ Unix 哲学を理解しない GNU が便利だと思ってオプションを追加したのだろう」と考えるかもしれません。しかし uniq 機能が組み込まれたのは Version 7 Unix、つまり Unix の開発者が組み込んだのです。これは 1
はじめに 多分これはガセネタです。おそらく日本だけで出回っているガセネタです。インタプリタにはそのような定義はありません。インタプリタは「ソースコードを読み込んで意味を解釈して実行するプログラム」 です。「1行ずつ」は些細な間違いとして「機械語に変換する」は完全に間違いです。ある程度詳しい人にとっては常識だと思うのですが。 おそらくコンピュータは機械語しか動かせないから、インタプリタも最終的に機械語に変換しているはずだという間違った思い込みからこのガセネタは広まってしまっているのでしょう。機械語に変換するのは面倒な処理です。速くなるかもしれませんが変換処理しなくて良いのだから普通はしませんよ。 コンパイラとインタプリタの定義 コンパイラとは コンパイラとは、ソースコードを元に実行可能なプログラムを生成するためのプログラムです。ユーザーは(ソースコードではなく)別に生成されたプログラムを実行
はじめに Windows NT は最初のバージョンから POSIX 準拠です。当時の POSIX で標準化されていた POSIX API を実装しており NIST が POSIX 準拠であると認めています。その資料も公開されています。 NIST(National Institute of Standards and Technology)とは、アメリカ合衆国の連邦政府機関の一つで、科学技術に関連する標準についての研究などを行う機関。主に度量衡や計測・計量についての標準を管理したり、関連する科学研究や技術開発を推進している。1988年に前身のNBS(National Bureau of Standards:国立標準局)から改組された。 いつの間にやら某所の Windows に関する POSIX の説明があまりにも酷いデタラメな内容に書き換えられていたので、ここに「1993年から Window
シェルスクリプトが速くなる! forkしない新しいコマンド置換がやってくる!(次期bash/zshの新機能)ShellScriptBashZshkshmksh はじめに シェルスクリプトを遅くする大きな原因は fork と exec です。この二つは OS のインターフェースである fork() 関数と exec() 関数のことで、シェルスクリプトからは、外部コマンドやバックグラウンドプロセスの実行、明示的なサブシェル (...)やコマンド置換 ret=$(...)、パイプの使用などで呼び出されます。 シェル関数はシェルの中で実行される関数であるため、単純にシェル関数を呼び出す場合には fork も exec も行われません。しかしシェル関数の出力を変数に代入しようとコマンド置換(var=$(func))を使うと、exec は行われませんが fork は行われてしまいます。その事に気づかず
シェルスクリプトの関数で「戻り値」を返す方法、全部まとめ(bash/zshの新機能 関数置換・値置換の使用例)ShellScriptBashZshkshmksh はじめに シェルスクリプトのシェル関数の return コマンドは他の言語のような戻り値を返すものではありません。return コマンドで返すものは終了ステータス、つまり 0 から 255 までの数値です。しかし現実には終了ステータス以外の値を返したいというのはよくあります。この記事ではシェル関数から「他の言語でいう戻り値を返す」に相当する方法をすべてまとめました。または次期 bash 5.3/zsh 5.10 で追加される予定の「関数置換 (funsub)」と「値置換 (valsub)」の機能の紹介です。 この記事では現時点で開発中の bash 5.3 と zsh 5.10 に追加される予定の「関数置換」と「値置換」の話を扱って
Windows は 1999年12月(ほぼ2000年なので上記では2000年としています)に発売された Windows 2000 まで POSIX サブシステムを搭載していました。2001年8月に発売した Windows XP では POSIX サブシステムを搭載するのをやめましたが、そのときにはもう米国政府の導入要件ではなくなっていました。POSIX が米国政府の導入要件ではないため POSIX サブシステムをやめたのかもしれません。だからといって Windows が POSIX システムとの互換性を諦めたわけではなく、Microsoft Windows Services for UNIX (SFU) という形で POSIX システムというより UNIX との互換性を実現していました。POSIX だけでは足りないからです。後に SFU は Subsystem for UNIX-based
はじめに 30年以上もの長い間 UNIX を支えてきた Bourne シェルも UNIX のサポート終了とともに消え去ろうとしています。みなさん、他のシェルへの移行はお済みでしょうか? 残り一年、まだ移行が済んでいないという人のために、移行のための簡単なガイドラインと各シェルの特徴をまとめました。 sh は昔は Bourne シェルのことでしたがそれも過去の話です。今どき「Bourne シェル」を解説している記事や sh のことを Bourne シェルと呼んでいる記事は情報が古い(大学関係に多い)、または古い情報を元にして書かれたか、シェルのことを正しく理解してない不正確な記事なので参考になりません。分かりやすい基準ですね。 関連記事 シェルとUNIXコマンドの未来 ~ これからの10年で起きるシェルスクリプトの変化 残り1年というのはどういうこと? Bourne シェルは POSIX に
はじめに シェルスクリプトの世界は今後 10 年で大きく変化します。10 年という数字は切りが良い数字を持ってきただけで根拠はありません。これより長い時間がかかるかもしれませんし、もしかしたら短くなるかもしれません。しかし確実によりよい方向に変わっていくでしょう。Unix/Linux の標準コマンドはさまざまな問題を抱えています。Unix/Linux の標準コマンドに依存している限りシェルスクリプトに大きな改善はありません。これからのシェルスクリプトの世界は Unix/Linux の標準コマンドに依存しない世界です。それがどういうものになるのかをこの記事で解説しています。この記事は私の予言であり目標です。 シェルスクリプトの失われた30年の進化を取り戻す! 残念なことに、シェルスクリプトの世界は 30 年前から大きく変わっていません。それまでの間、プログラミング言語の世界、ソフトウェア開発
マルチライナー記法とは? マルチライナー記法とは、その名の通りシェル芸をワンライナーではなくマルチライナー(複数行)で書くことです。長すぎる行をワンライナーで書くと以下のように横スクロールが必要になって非常に読みにくくなります。(コードは Convert long single line command to a bash shell script より借用。長いコードとして利用しているだけで中身に意味はありません)。マルチライナー記法はこのようなワンライナーを読みやすく書くことです。 nice --20 iperf3 -c somelocation.com -f k | while IFS= read -r line; do echo "$(date) $line"; done | tee onespeed.txt | tee -a speeds.txt; sleep 30 ;cat o
xargs 完全理解マニュアル - xargs は拡張引数 (extended arguments) の略って知っていますか?ShellScriptUNIXシェル芸POSIXUnix哲学 はじめに xargs コマンドは「なにか凄そうだけどよく分からないコマンド」としてよく知られています。使う人は使うけど何をやっているのか全くわからないコマンドです。また、やっていることがわかっても実際に使ってみると、空白やクォーテーション文字でエラーになってしまう使い方がとても難しいコマンドです。この記事はそういうよくわからない xargs はどういうコマンドなのか解説します。この記事を読むと xargs を「完全に理解した」と言えるようになるでしょう。 xargs コマンドが難しい理由は、xargs 自体の設計や実装の問題で古い時代の制限が多いからです。仕様が意味不明で一貫性がなくで他のコマンドと正しく
はじめに readlink コマンドと realpath コマンドは、どちらもシンボリックリンクを解決し、指定したパスの実体がある場所を探すコマンドです。後ほど解説しますが、シェルスクリプトを書くときに非常に重要なコマンドです。 readlink コマンドと realpath コマンドは多くの環境で使えるようになり、POSIX.1-202x (Issue 8) で標準化されました。一般的に標準化は実装された後に行われるため、使ったことがある人は多いでしょう。ほとんどの環境ですでに実装ずみであるため気兼ねなく使えるようになりました。もし古い使えない環境にも対応したい場合には、私が readlink -f と互換性がある readlinkf 関数を作っているので環境が対応するまでそれを使用して時間稼ぎができます。 readlink コマンドと realpath コマンドを使ったことがある人は、
はじめに kill コマンドと trap コマンドはシェルでシグナルの送信と受信を行うためのコマンドです。このコマンドは意外と適切ではない使われ方をよく見かけます。この記事では kill と trap の基礎知識を解説します。 POSIX準拠のkillコマンドの構文 POSIX で標準化されている kill コマンドの使い方は次のとおりです。POSIX で標準化されているというのは移植性が高い書き方ということを意味しています。シグナル名の指定には -s オプションが必要です。そして signal_name であって signal_number でないことに注意してください。POSIX シェルの世界にシグナル番号という概念はありません。シグナル番号を指定した書き方は避ける方をおすすめします。
はじめに set -o pipefail は POSIX で標準化されているシェルオプションです。パイプラインにおけるエラーを確実に検出するために、シェルスクリプトでは基本的に使うようにしましょう。 某コメントより “set -o pipefail は標準化されました” っていってここ何年かの標準化を無邪気に正当化できるのいいなと思う(目の前のターミナルを見ながら) どのシェルを今使っているのか聞きたいですね。商用 Unix を含む主流の環境で、すでに何年(十数年、数十年)も前から set -o pipefail は実装済みなんですが? おそらくシェルの事をよく知らないで言ってるのでしょう。私は標準化の有無は関係なく実際のシェルのことを調べ尽くして言ってるわけで無邪気に正当化とか失礼な話です。標準化とか気にしてるから何年(十数年、数十年)も前に実装された便利な機能が使えないんですよ。自業自
はじめに コマンドをパイプでつなげた時、各コマンドの間にはいくつかのバッファが存在します。そのバッファについてちゃんと意識しているでしょうか? バッファの存在によって各コマンドの実行には分かりづらい変化があります。そのバッファを知らないと罠にハマってしまう・・・かもしれません。 プロセス間のパイプ通信のバッファ まずプロセス間のパイプ通信に存在しているバッファです。多くのコマンドは行単位でデータを処理しますが、一般的にパイプでつなげた各コマンドはそれぞれ処理速度が異なります。処理がすぐに終わるコマンドもあれば時間がかかるコマンドもあります。各コマンドは並列で動作可能ですが必ずしも並列で動作するわけではありません。 一般論としてパイプライン全体の処理にかかる実時間はパイプでつながったコマンドの中で一番遅いコマンドに足を引っ張られます。いくら並列で動作可能と言ってもデータが到着しなければ処理す
はじめに 一般的にファイルの最終行に改行がないデータを扱うのは良い考えとは言えません(よくない理由は別記事で書きます)。しかしそれでも扱いたい場合もあります。この記事ではその方法をまとめました。 この記事は シェルスクリプト&PowerShell Advent Calendar 2023 2日目の記事です。 ファイルの末尾に改行が必要なのは「POSIXの仕様」だとする説がありますが、これは間違いで POSIX は標準規格で使用している「テキストファイル」の用語を定義しているだけです。 POSIX では「テキストファイル」という用語を、0行以上の行で構成されたファイルと定義しており、行とはヌル文字がを含まず末尾に改行がある LINE_MAX バイト(一般的に2048バイト)以内の文字列のことです。 詳細は以下を参照してください。 「POSIXがファイルの末尾に改行が必要と決めた」はガセネタ
sort -u と sort | uniq は同じじゃないよ ~ 文字の順番とロケールとPOSIXと現実の実装のめんどくさい話ShellScriptBashLinuxUNIXPOSIX はじめに sort コマンドの -u オプションは重複行を取り除くオプションです。-u は 1979 年の Vesion 7 Unix のときからある古いオプションで、シェルスクリプトに詳しいと自負している人でこのオプションを知らなければモグリでしょう。uniq コマンドは重複行を取り除くコマンドです。「現在のすべての問題が解決された場合」は sort -u と sort | uniq はほぼ同じになるのですが、実際には異なる結果を返すことがあります。この記事ではその問題について解説します。 前提知識: sort-u と uniq の正しい理解 この記事の話とは少し異なりますが前提知識として sort コマ
次のページ
このページを最初にブックマークしてみませんか?
『@ko1nksmのマイページ - Qiita』の新着エントリーを見る
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く