Ubuntu上のFSLやFreeSurferでsyntax errorが出る時の対処法

Ubuntu上でFSLやFreeSurferを走らせる時、

Syntax error: "(" unexpected.

といったエラーが出ることがあります。

この原因を探っていたらわかったことがありました。

FSLのプログラムは、基本、bashで動くことを前提にしていますが、ファイルの冒頭のShebang行は、#!/bin/shとなっています。

RedHatやCentOSは、/bin/sh は、bashにシンボリックリンクが張られていますが、
Ubuntuでは、dashにシンボリックリンクが張られています。
ls -l で確認するとすぐに確認できます。

$ ls -l /bin/sh
lrwxrwxrwx 1 root root /bin/sh -> dash

dashとbashは完全に互換性がないため、ときにbashの文法が通用しないことがあります。

解決策は以下の2つです。

  1. シェルスクリプトのShebang行を #!/bin/bash に変更する
  2. 自分でシェルスクリプトを書く場合などはこれがいいでしょう。
    しかし、FSLでは、300以上のスクリプトがありますので、これを全部変えるのはめんどくさいですね。

  3. dpkg-reconfigureで、dashをbashに変更する
  4. Ubuntuでは、 dpkg-reconfigure dash というコマンドで、dashを使わずにbashを使うようにすることができます。

    インタラクティブに行うには、以下のコマンドを叩きます。

    $ sudo dpkg-reconfigure dash
    

    すると、次の画面が出るので、「いいえ」を選びます。

    再度、/bin/shのシンボリックリンク先を確認してみます。

    $ ls -l /bin/sh
    lrwxrwxrwx 1 root root /bin/sh -> bash
    

    今度はbashに変更されていることがわかります。

    なお、インタラクティブでなく変更したい際は、以下で行います。
    いくつかのサイトで情報が提供されていましたが、正しくないものもありましたので、試行錯誤した結果、以下が最適な解決法とわかりました。

    echo "dash dash/sh boolean false" | sudo debconf-set-selections
    sudo dpkg-reconfigure --frontend=noninteractive dash
    

bashのtips: 直前の引数を利用したいときは !$

私はこんな作業をよくします。

  • あるファイルをディレクトリAにコピー
  • ディレクトリAに移動

この際

$ cp something /path/to/A
$ cd /path/to/A

とするわけですが、この /path/to/A を2回うつのはめんどくさいので、簡単な方法がないかを調べてみると、

!$

という特殊変数があることがわかりました。
しかし、しょっちゅう忘れるので、覚え方を考えてみました。

bashでは、履歴を知りたいときに、!を使います。
たとえば

$ history

でコマンド履歴を調べ、その1457番目のコマンドを再度実行したいときは

$ !1457

とすればいいわけですね。

で、$ですが、正規表現において、$は「行の最後」を意味します。

この2つを組み合わせれば

「履歴において一番最後のもの」

と考えれば、 !$

は覚えやすいなと思いました。

自分の思考過程を備忘録として書いておきます。

BashからMatlabスクリプトを実行する方法

先日、ある方と「BashからMatlabを呼び出せないだろうか」という話をしていました。もし、これができたら、シェルスクリプトから、Matlabを呼び出せるので、シェルとMatlabを完全に連携できるわけです。

結論としては、以下でできました。

  • Short answer
  • Matlabのスクリプト名を sample_code.m とすると、以下でできます。

    $ matlab -nodesktop -nosplash -r 'sample_code; exit'
    

    コツは2つです。

  • スクリプト名ではなく、コマンドとして指示するため、.mは外す
  • Matlabから抜けるために exit を追加する

続きを読む

Linuxでfind, sedを使いながら文字列を再利用してファイル名の途中に文字列を挿入する方法

最近、以下のようなことをやる必要がありました。

ファイル名が

201105_ID.jpg
20120608_ID.jpg
20130704_ID.jpg
201409_ID.jpg

となっているファイル(年月が必ずあり、日が時についている)に対して、
年の後にアンダースコアを入れたい、つまり、

2011_05_ID.jpg
2012_0608_ID.jpg
2013_0704_ID.jpg
2014_09_ID.jpg

としたいわけです。

続きを読む