質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
シェルスクリプト

シェルスクリプトは、UNIX系のOSもしくはコマンドラインインタプリタ向けに記述されたスクリプト。bash/zshといったシェルによって実行されるため、このように呼ばれています。バッチ処理などに使用されており、テキストファイルに書かれた命令を順に実行します。

Q&A

6回答

1725閲覧

シェルスクリプトの改行コード

iii

総合スコア29

シェルスクリプト

シェルスクリプトは、UNIX系のOSもしくはコマンドラインインタプリタ向けに記述されたスクリプト。bash/zshといったシェルによって実行されるため、このように呼ばれています。バッチ処理などに使用されており、テキストファイルに書かれた命令を順に実行します。

0グッド

0クリップ

投稿2018/04/04 01:48

シェルスクリプトでは改行コードをLFにしないといけないと聞いたのですが
それはなぜですか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答6

0

根幹の答えとしては「UNIXの標準規格と言えるPOSIXで、そう決められているから」です。

stack overflowで同様の質問がされていたのでご案内します。
[Why should text files end with a newline?]((https://stackoverflow.com/questions/729692/why-should-text-files-end-with-a-newlinej)

この中の回答を引用させていただきますが、

Because that’s how the POSIX standard defines a line:
3.206 Line
A sequence of zero or more non- <newline> characters plus a terminating <newline> character.

とあります。ソースはIEEE Std 1003.1-2017のこちらです。 3.206 Line

直訳すると、「0、または1文字以上の<newline>以外の文字と、終端の文字<newline>をもって、「行(line)」とする。」
とあります。

尚、CR+LF形式でコーディングすると、シェルによってはシェルスクリプトが動作しません。


**追記しました:**2018/04/04 11:30
自分の回答を読み直してみて、少し直接的でない部分もあったと思いましたので補足します。

LF(0x0A/newline)のみを行の終端として扱うのがPOSIX準拠のUNIXのプログラムであるならば、bashのようなシェルにとってはCR(0x0D)が行の終端のLFの前にあると、

「なんだこのキャラクターは?! こんなものは処理の対象外だ!エラーだ!エラー!!」

と認識して動作しても正しい仕様ですので文句は言えません。なので、CR+LF ではダメだと言えることにつながります。


**更に追記:**2018/04/04 13:41

「なんだこのキャラクターは?! こんなものは処理の対象外だ!エラーだ!エラー!!」

コメントでご指摘を受けたように、確かに語弊がありました。"\r"(CR)自体がエラーになるのではなくて、
bash で語句分割を行った後、"\r"を結局どう扱うかに依存しているようでした。

Cygwinでのbashスクリプトの実行結果です。do01_LF.sh は"\n"(LF)のみ終わるbashシェルスクリプトです。対して、do01_CRLF.sh は"\r\n"(CRLF)で終わる同じ内容のスクリプトです。

otnさんの別回答にありますが、WindowsのCygwin版のせいか、bashのバージョンによるのか、コードの各行が"\r\n"で終わっていてもそれ自体には問題なく動作しています。

$uname -a CYGWIN_NT-6.1-WOW turtle0 2.10.0(0.325/5/3) 2018-02-02 15:21 i686 Cygwin $ cat do01_LF.sh #!/bin/bash V1=1 if [ $V1 -eq 1 ]; then echo "TRUE" else echo "FALSE" fi $ $bash --version GNU bash, バージョン 4.4.12(3)-release (i686-pc-cygwin) Copyright (C) 2016 Free Software Foundation, Inc. ライセンス GPLv3+: GNU GPL バージョン 3 またはそれ以降 <http://gnu.org/licenses/gpl.html> This is free software; you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. $./do01_LF.sh TRUE

問題無く動きます。これを改行コード"\r\n"(CRLF)のdo01_CRLF.shで実行すると

$./do01_CRLF.sh ./do01_CRLF.sh: 行 2: $'\r': コマンドが見つかりません ./do01_CRLF.sh: 行 10: 構文エラー: 予期しないファイル終了 (EOF) です $

となります。shebang行の下の2行目は空行ですが、「./do01_CRLF.sh: 行 2: $'\r': コマンドが見つかりません」と報告されます。bash自身のエラーと言うわけではありません。"\r"をコマンドと認識しているように見えます。

投稿2018/04/04 02:10

編集2018/04/04 04:49
dodox86

総合スコア9183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2018/04/04 03:39

> 「なんだこのキャラクターは?! こんなものは処理の対象外だ!エラーだ!エラー!!」 これは語弊がありますね。直接的にエラーにはならないですよ。 特別な意味を持たない単なる文字なので、 A=foo<CR> だと、Aに "foo\r" がセットされます。
dodox86

2018/04/04 04:42

ご指摘どうもありがとうございました。確かに語弊がありました。まさに<newline>以外の文字のひとつと認識しているだけでした。
guest

0

Windows用にコンパイルされたbashだとCRを無視するようです(MinGWで確認)。
例えば、dateという文字列の途中にCRがあっても、ちゃんとdateコマンドが実行されます。

それ以外の環境では、CRは単なる文字なので、改行がCRLFだと、例えば全部の行末にAと書いてあるような物です。
つまり、

Bash

1#!/bin/bashA 2dateA 3echo 1 2 3A

と同じことなので、普通はそういう名前のファイルが見つからずエラーになります。

別の言い方をすると、(CRを<CR>で表すと)

Bash

1#!/bin/bash<CR> 2date<CR> 3echo 1 2 3<CR>

をエラー無く実行したい場合、あらかじめこうしてCRつきのファイルを作っておけばいいです。
「CRは単なる文字」というのはそういう意味です。

Bash

1sudo cp /bin/bash $'/bin/bash\r' 2sudo cp /bin/date $'/bin/date\r'

(あるいは、shbang行以外は、行末に#を書いておけばCRがコメントになるのでそれでもOK)

投稿2018/04/04 04:15

編集2018/04/04 05:03
otn

総合スコア84498

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2018/04/04 05:13

昔のbashはもっとダメ率が高かった気がするのか、ただのbシェルの記憶と混ざってしまっているのか不確かなのですが、今回、認識を新たにしました。ありがとうございます。 cp /bin/bash $'/bin/bash\r' と行末#コメントは想像だにしない解法でした。
otn

2018/04/04 05:22

後で気づきましたが、(ソースは見てませんが) bashは argv[0] を見て動作を変えているはずなので、別名にコピーした場合、bashの機能をフルに使えないかも。
dodox86

2018/04/04 05:28

(私宛にコメントいただいた訳ではないかもしれませんが) > bashは argv[0] を見て動作を変えているはずなので フォローありがとうございます。組み込み用のシェルBusyBoxのようですね。いずれにしても興味深い解法のご提示でしたので、別でも何かに使えそうです。
otn

2018/04/04 06:32

man bashより > sh という名前で bash を起動すると、 bash は古くからある sh の起動動作を できるだけ真似しようとします。 "sh"と同一かで見ているのか、"bash"と同一かで見ているのか不明なので、"bash\r"の場合どっちか不明。
guest

0

単純に改行コードがCRLFだとスクリプト実行時にエラーを引き起こす要因となるからです。

もしLinux環境でCRLFを含むスクリプトを実行した場合、CRLFは[CR][LF]と別々のものとして認識され、かつ[CR]は不必要なゴミとして扱われます。
このゴミの厄介なところは、コマンドやコマンドオプションによってエラーになるかが変化する点です。

であれば、厄介な要因は潰すに越したことはないので、LFを使用するのが無難かと思われます。

投稿2018/04/04 02:51

A.fine

総合スコア40

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

改行コードは、OS依存です。

Unix系(UNIX、各種Linux)では、LF(\n)
Windows系では、CRLF(\r\n)
Mac OS(9以前)では、CR(\r)

投稿2018/04/04 02:48

coco_bauer

総合スコア6915

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

Linux上で動かすシェルスクリプトの場合、CRLFにしているとシバン行でエラーとなることがあります(Qiita)。

投稿2018/04/04 02:09

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

今は、LFでもCRLFでもOKだと思いますが。
それは、質問者さんの属する組織のコーディングルールなのではないですか。

投稿2018/04/04 01:58

ikapy

総合スコア1167

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yoorwm

2018/04/04 02:05

いや、bashだとCRLFだとエラーが出るんですよ
ikapy

2018/04/04 13:04

そうですか、私に思いこみですね。続々と新しい知見が出ていますので私の回答は無視してください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問