ラベル bash の投稿を表示しています。 すべての投稿を表示
ラベル bash の投稿を表示しています。 すべての投稿を表示

2016-09-05

ffmpeg でメディア・ファイルのコーデックを調べる

先日の mediainfo コマンドの記事に対して、ffmpeg でも同じことを調べられると教えてもらった。

試してみた:

$ ffmpeg -i ~/Movies/google_spreadsheet_1.mov
ffmpeg version 2.8.2 Copyright (c) 2000-2015 the FFmpeg developers
  built with Apple LLVM version 7.0.0 (clang-700.1.76)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/2.8.2 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-opencl --enable-libx264 --enable-libmp3lame --enable-libvo-aacenc --enable-libxvid --enable-vda
  libavutil      54. 31.100 / 54. 31.100
  libavcodec     56. 60.100 / 56. 60.100
  libavformat    56. 40.101 / 56. 40.101
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 40.101 /  5. 40.101
  libavresample   2.  1.  0 /  2.  1.  0
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  2.101 /  1.  2.101
  libpostproc    53.  3.100 / 53.  3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/Users/ataka/Movies/google_spreadsheet_1.mov':
  Metadata:
    major_brand     : qt  
    minor_version   : 0
    compatible_brands: qt  
    creation_time   : 2014-04-29 11:10:42
  Duration: 00:02:40.05, start: 0.000000, bitrate: 1419 kb/s
    Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 682x516, 1402 kb/s, SAR 1:1 DAR 341:258, 60 fps, 60 tbr, 6k tbn, 50 tbc (default)
    Metadata:
      creation_time   : 2014-04-29 11:10:42
      handler_name    : Core Media Data Handler
      encoder         : H.264

なるほど。ビデオが H.264 (AVC1) だって分かった。mediainfo だと AVC とだけ出て来ていたけど、MPEG-4 AVC と H.264 は同じ規格だから特に気にする必要はないのかな。

あ、ffmpeg の出力は標準エラー出力に出るのか。less で眺める時は、気を付けないと。

$ ffmpeg -i ~/Movies/google_spreadsheet_1.mov 2>&1 | less

2015-08-03

重複したキーを探すワンライナー

キーと値を = でつないだファイル keys.txt があって

"key_name_with_underscore" = "value";

重複したキーがないかチェックするのにワンライナーを書いたのでメモ。

$ awk '{print $1}' keys.txt | sort | uniq -d
  • awk コマンドで 1 列目だけ (ここではキー部分) を出力
  • sort コマンドでソート
  • uniq コマンドに -d オプションを付けて重複しているものだけ出力

久しぶりに awk コマンドを使ってみた。書き方忘れててネットで調べた。

2015-07-17

行数の多いファイル、トップ 10 を出力するワンライナー

この前、カレント・フォルダーにあるファイルで一番行数の多いファイルは何か? という話が出て、その場で書いたワンライナー。

$ wc -l * | sort -n -r | head -10

wc-l オプションを付けて、行数をカウント。

そのままじゃ、ファイル名順に並ぶので sort コマンド。-n オプションで行数を文字列じゃなく、数字として扱わせて、-r オプションで多い順にする。

最後に head コマンドで最初の 10 行を取り出した。

この方法だと、wc が出力した全てのファイルの「トータル行数」が一番上に出る。ああ、そうか。すると、トップ 9 になっちゃう。トップ 10 を出すなら、head の引数を 11 にしなくちゃいけない。

もしくは、tail コマンドを使って、一番上の行を削るかな。

$ wc -l * | sort -n -r | tail -n +2 | head -10

ワンライナー。サクッと書けるようになると楽しい。

2014-12-08

空白を含む引数を bash script に渡す

空白混じりの引数を受け取る、bash script の書き方。先日までは引数の「渡し方」を書いてたけど、今回は空白混じりの引数を「渡される側」について。

例えば bash script が 2 つあったとする: a.sh と b.sh

a.sh は b.sh を呼び出す。

#! /bin/bash

token=foo
name="Ludwig van Beethoven"

bash b.sh $taken $name

b.sh は引数を受け取って処理を行なう。例えば、こんなコード

#! /bin/bash

option='-foo -bar'
token=$1
name=$2

some-command $option $token $name

この時、変数 name には二番目の引数が入る。a.sh で渡す「二番目」の引数は "Ludvig van Beethoven" なので、変数 name にもその値が入っていることを期待したくなるけど、実は "Ludvig" という値しか入っていない。引数 "Ludvig van Beethoven" は空白で分割されて 3 つの引数になってしまう。

今回の b.sh の例だと、$3, $4 に "van" と "Beethoven" が入る。

これは嬉しいくない。そこで、変数 $* を使う。すると、空白を含む引数をひと固まりに扱うことができる。引数が 2 つある (今回の様な) 場合なら、shift を使うとスマートにコードが書ける。

#! /bin/bash

option='-foo -bar'
token=$1
shift
name=$*

some-command $option $token "$name"

some-command に渡す引数は一応 "" で囲んでおく方が安全。

あとがき

shell は「空白」を引数の区切りにするので、ハマりやすい。というか、実際にハマりまくったので、メモとして残しておく。

2014-12-05

空白を含む path を bash 変数にして cd する

昨日の続き。

path に空白が含まれていることがある。純粋な Unix 系のディレクトリー構成では見られないけど、Windows や Mac だとタマに... 有名な所では Windows の Program Files とか、Mac の ~/Library/Application Support/ とか。

コマンドライン派の人間が好んで「空白を含む」ディレクトリーを作ることはないので、他人のソースを扱う時や、開発環境が元からそういう仕様だったりして悩まされるかな。

これも、.bashrc に変数として保存できれば楽なんだけど事は楽に進まない。

foodir="/path/to/dir with space"

上の様に「dir with space」という空白入りのディレクトリーに移動したいとする。

そこで変数を使って cd しようとするとエラーになる。

$ cd $foodir
bash: cd: dir: No such file or directory

dir というディレクトリーはないと怒られた。実は変数が渡される時、bash shell によってスペースが「引数の区切り」になってしまっている。この場合、$foodir/path/to/dir with space に展開された後、cd コマンドに /path/to/dirwithspace の 3 つの引数が渡されてしまっている。本当は一つの引数として渡したいのに...

解決策は泥臭いけど、変数を " で囲む。

$ cd "$foodir"

コマンドラインから空白入り path へ移動するのは面倒なので、少し面倒でも助かる。

shell script を作ってる時でも、同じトラブルは起きる。むしろ、shell script でハマる時の方が重症かもね。

2014-12-04

dir path を bash 変数に入れて、dir alias にしている

bash の変数に Directory Path を設定して、cd コマンドでの移動に役立ててる。

例えば、こんな感じ

$ cat .bashrc | grep blog
blog="$HOME/Documents/blog/"

で、コマンドラインからは次のように使う。

$ cd $blog

ぼくはコマンドラインから git コマンドを直接叩くことも多いので、この手の変数を用意している。移動が楽になって便利。特にプログラム・ソースを深い階層に置いていても、移動が一発なので助かってる。

2014-10-08

*.png から *@2x.png を convert コマンドを使って作成する shell script

iOS の開発をしていると、Retina ディスプレー用に 2 倍サイズの画像 (@2x.{png,jpg}) を求められる。画像の数が多いと面倒なので、convert コマンドでリサイズする shell script を書いてみた。コードは 2 行。ワンライナーにならなかったのは無様だけど、まあ、そこまで気負うこともないか... と手を抜いた。

以下、カレント・ディレクトリーの中にある画像ファイルをオリジナル・サイズ (@2x 画像) として、半分のサイズの画像を作るコード。

for i in `ls *.png`; do j=${i%.*}; mv $j.png [email protected]; done

まずはカレント・ディレクトリーの中にある *.png ファイルを *@2x.png にリネームする。

for i in `ls`; do j=${i%@*}; ext=${i#*.}; convert -resize 50% $i $j.$ext; done

次のコードは、*@2x.png ファイルから convert コマンドを使って半分のサイズの *.png ファイルを作成する。

bash の機能を使っている。

  • j=${i%@*} は @ より前のファイル名を取得する
  • ext=${i#*.} は . より後のファイル名 (この場合、拡張子に当たる) を取得する

変数 i が [email protected] だとすると、変数 j には foo、変数 ext には png の文字列が入る。このコードは、拡張子が png でなくとも (jpeg でも jpg でも gif でも) 問題なく動く。

convert コマンドのオプションには -resize のみを使っているけど、本職の人に言わせると、もっと別のオプションを追加して画質を上げたりしたいかと思う。そこら辺は別のサイトを見てお好みにどうぞ。

2014-08-09

bash 変数を使って cd を楽にする方法

深い階層へ軽動したい時、cd コマンドを打つのは面倒。たとえ bash のパス補完が効くとしても、手間はかかる。そこで、目的のパスを bash 変数に保存することでこの問題の対処をしている。例えば、このブログ記事の下書きが置いてあるディレクトリーへ移動するには、次のコマンドを使う:

$ cd $blog

.bashrc に書く設定は次の通り:

blog="$HOME/Documents/blog/"

ディレクトリー階層がどんなに深くても、この方法なら一発で辿り着けるので便利。

パスに空白が含まれる場合

時として、パスに空白が含まれる場合がある。自分でそういうパスを作ろうとは思わないけど、他人の git repository を clone したらパスに空白が空いていた、等々何ともしがたい状況はある。そういう時、同じ要領で変数を指定しても cd で失敗する。

$ grep somedir ~/.bashrc
somedir="$HOME/Documents/path with space"
$ cd $somedir
bash: cd: /Users/ataka/Documents/path: No such file or directory

path の中に含まれる空白が引数の区切りとして扱われている。「path with space」というディレクトリー名の最初の「path」しか cd に渡っていない。これを解決する方法は、多少武骨だけれども変数を "" で囲む。

$ cd "$somedir"

これで「path with space」へと移動できた。

あとがき

ディレクトリー移動はコマンドライン操作の基本。ここで楽できると、随分ストレスが減る。もし良ければ試してみて欲しい。

2013-04-13

git のカラー化と log の文字化け

git の出力をカラー化する

git status にせよ、git log にせよ、色が付けば嬉しいもの。色を付けるには次のコマンドを打つだけ。

$ git config --global color.ui auto

試しに git status。

うん、綺麗に表示されてる。

トラブルシューティング

さて、ディストリビューションによっては git log すると文字化けをおこすことがある。git status だと問題ないのに、git log だと駄目。

その理由は?

git log はログを眺めるために PAGER ツールを使っているから。普通は less が使われる。この less がカラー対応していないと、色出力用のコードがそのまま見えて「文字化け」したかの様に見える。

less ならば -R オプションを、lv なら -c オプションかな。git の PAGER 設定で対策するのも手だけれども、カラー出力するのは git だけじゃないので、.bashrc なりに alias を突っ込んじゃいましょ。

\
alias less="less -R"

これで git log してもカラー化されたログを眺めることができる。

満足、満足。

2012-04-16

カレント・ディレクトリー内の全てのファイルを新しい下位ディレクトリーに簡単に移動させる 〜 dot dir を使って

ファイルが多くなったので、ディレクトリーを作ってまとめちゃう。そんなことは良くある。そのやり方が目から鱗な方法が紹介されていたので、コピペ。

$ ls
a.txt b.txt c.txt
$ mkdir .dir
$ mv * .dir
$ mv .dir dir

dir は適当なディレクトリー名をお付け下さい。

このやり方で何が目から鱗って、下から二行目のコマンド「mv * .dir」。カレント・ディレクトリーの全てのファイルを * で表しているわけだけど、それだと移動先であるディレクトリーも含まれてしまう。自分自身を自分の中に移動は出来ないのでエラーが出る。そこで、移動先のディレクトリーだけ排除して mv コマンドを実行したい。ここで、* (アスタリスク) が dot dir を含めないことを利用した。

一般に UNIX では、「.」で始まるファイル/ディレクトリーは隠しファイル/ディレクトリーになる。予め隠しディレクトリー「.dir」を mkdir で使っておき、mv コマンドで * (全てのファイル) をその .dir へ移動させる。.dir は隠しディレクトリーだから、「*」には含まれない。つまり、難しいことを考えなくても良い!!

作業が終わったら、隠しディレクトリーを適切なディレクトリー名に変更する。ちょっと手間だけど、難しいことを覚えてたり、ひねった作業をするよりスマートで簡便。急がば回れ的に便利なやり方。感動。

蛇足

ぼくは、この手の作業をする時、一つ上の階層にディレクトリーを作っていた。

$ mkdir ../dir
$ mv * ../dir
$ mv ../dir ./

この方法の欠点は二つ。一つは、一つ上に同じ名前のディレクトリーがあると mkdir の時にエラーになる。かと言って、確認するのも面倒。もう一つは、上のディレクトリーのパーミッションがない場合がある。特に管理者関係の作業をしていると、パーミッション問題にひっかかる。今回知った方法は、これら二つの欠点を全く見事にクリアーしている。いいね。

2010-12-23

Linux から NAS を mount する (その 2)

先日、BUFALO の USB メモリー・スティック型 SSD を買った。これを、Apple の AirMac Extreme の USB ポートに挿して NAS のように使っている。

BUFFALO 高速40MB/s USBメモリー型 SSD 64GB SHD-LV64GS-BK

さて、この SSD を Linux から mount したい。正しい方法が分からないので、試行錯誤の上でやったことをメモしておく (コメント大歓迎)。

Mac 側の作業

まず AirMac Extreme の IP アドレスを調べる。これは Mac から簡単に調べられる。

そして、SSD にユーザー foo を追加する (foo は適当に変えて下さい)。

Linux 側の作業

まず /etc/hosts に AirMac Extreme の名前を追加する。ここでは base という名前にした。

192.168.0.60 base

AirMac Extreme の IP アドレスが変わることは、運用上ほとんどない。ただし、AirMac Extreme を再起動させたり、停電が起きたら IP アドレスが変わるので、その場合は /etc/hosts を書き直す。

次に /usr/local/bin/base.sh というファイルを作る。中身はこんな感じ:

#!/bin/sh
mount -t cifs //base/foo /mnt/smb --verbose -o user=foo,password=******,rw,noperm,iocharset="utf8"

smbmount より mount -t cifs を使う。AirMac Extreme に挿さった SSD へは //base/foo でアクセスできる。これを /mnt/smb にマウントする。ユーザー名・パスワードは面倒なので base.sh の中に書いちゃった。あと、SSD 内ではファイル名が Shift_JIS になっているので文字化けしないよう iocharset オプションを追加していいる。

base.sh の用意ができたら、マウントする時は sudo bash.sh、アンマウントする時は sudo /mnt/smb で OK。

ref

2010-12-22

Linux から NAS を mount する (その 1)

先日、BUFALO の NAS、LinkStation Mini を買った。

BUFFALO 40MB/s DTCP-IP対応 高速ホームサーバー Link Station mini 1.0TB LS-WSX1.0TL/R1WH

B002UD6CJ8
バッファロー 2009-11-13
Amazonで詳しく見る
by G-Tools

Windows や Mac からのアクセスは専用ソフトがあるので楽だけれど、Linux からアクセスする場合一手間かかる。とりあえず、これが正当な方法かは分からないけれど、ぼくのやったことをメモしておく。

LinkStation Mini 側の設定

LinkStation Mini のウェブ設定画面を開き、ユーザー foo を追加する (foo の部分は適当に変えて下さい)。すると、LinkStation 内に /share/foo というフォルダーができる。このフォルダーを Linux から mout する。

また、Windows/Mac 側から LinkStation Mini の IP アドレスを予め調べてメモしておく。

Linux 側の設定

まず、LinkStation Mini の IP アドレスを /etc/hosts に追記する

(例)

192.168.0.50 nas

次に /usr/local/bin に次の nas.sh という shell script を作って置く。nas.sh の中身は次の通り:

#!/bin/sh
mount -t cifs //nas/share/foo /mnt/smb --verbose -o user=foo,rw,noperm

sudo nas.sh することで、NAS の中身が /mnt/smb に mount される。

smbmount コマンドよりも mount コマンドでタイプを CIFS にする方が効率が良いらしい。

アンマウントする時は sudo /mnt/smb を使う。

2009-05-31

Ubuntu 8.04 でサスペンド復帰後に音が出なくなる不具合の対策

Ubuntu 8.04 でサスペンドすると、復帰後に音が出なくなってしまう。ネットで調べたところ、音関係の module を再読み込みすればよいことが分かった。

具体的には、modprobe コマンドを使って snd_hda_intel モジュールを一度削除して、その後もう一度インストールする。

コマンドを毎回打つのは大変なので、shell script を作った。

#!/bin/sh

pm=pm-suspend
snd=snd_hda_intel

sync && $pm && modprobe -r $snd && modprobe $snd

こいつを /usr/local/bin に pm-suspend-snd.sh という名前で置いて、sudo コマンドで呼び出してやる。

$ sudo pm-suspend-snd.sh

Suspend じゃなくて Hibernate したい場合は、pm=pm-suspendpm=pm-hibernate に変更されたし。

ソースコードは gist に登録してあるので、git 使いの人はこちらから最新版をどうぞ。

$ git clone git://gist.github.com/120717.git pm-suspend-snd

注意点

どっかのプロセスが snd_hda_intel を掴んでいると、modprobe -r に失敗する。エラー・メッセージはこんな感じ:

FATAL: Module snd_hda_intel is in use.

原因の一つは、GNOME の音量調節アプレット。アプレットを右クリックして削除してしまうのが一番簡単な解決策。

もう一つは pulseaudio。これが何のコマンドか知らないけだけど、次のコマンドを打つと pulseaudio を殺せる。もしかしたら、アンインストールしてしまってもいいのかもしれない。

$ pulseaudio -k

後はオーディオ関連のコマンド。何気に firefox が音を掴んで離さないことが多い。

2006-08-03

ps + grep の Tips

Linux でプロセスごとの実メモリー使用量 (RSS) を調べるのに、ps と grep を使う方法を先日書いた。

sawfish の RSS を調べるには、ps alx | head -1 && ps alx | grep sawfish とするんだったね。実行結果は次のようになる。

F   UID   PID  PPID PRI  NI   VSZ  RSS WCHAN  STAT TTY        TIME COMMAND
0   666  3173  3147  15   0 11596 4976 -      S    ?          1:16 sawfish
0   666  4185  1733  23   5  5708  716 -      RN   pts/507    0:00 grep sawfish

この方法の欠点は、grep しているプロセス自身も引っかかってしまうこと (上例の最下行)。これは、見苦しいね。

この件について、OKAMURA さんが、コメントでアドバイスを下さった。ここに引用しやう。

s + grep で目的のプロセスだけの情報を抜き取るとき

grep sawfish

ではなく

grep [s]awfish

とすると grep の情報が出ないので便利ですよ。

ぼくの環境だと、[] が zsh に展開されてしまうので、grep "[s]awfish" とする必要があったけど、いいこと教えて頂いた。OKAMURA さん、ありがとう。

shell script psl

さて、複数プロセスのメモリ使用量を調べる場合、コマンドラインがちょっと複雑になる。そこで、psl なる shell script を組んでみた。次のようにして使う。

$ psl firefox emacs
F   UID   PID  PPID PRI  NI   VSZ  RSS WCHAN  STAT TTY        TIME COMMAND
0   666 12520  3179  25   5  5116  952 wait4  SN   pts/14     0:00 /bin/sh /usr/local/bin/firefox/firefox
0   666 12523 12520  26   5  6356  1112 wait4 SN   pts/14     0:00 /bin/sh /usr/local/bin/firefox/run-mozilla.sh /usr/local/bin/firefox/firefox-bin
0   666 12528 12523  20   5 363576 173512 -   SN   pts/14    20:18 /usr/local/bin/firefox/firefox-bin
0   666 23237  3179  20   5 56436  50380 -    SN   pts/14   107:12 emacs

ソース・コードは下記:

#!/bin/sh

ps='ps alx'
psl=$0
$ps | head -1
for i in $*
do  command='['${i:0:1}']'${i:1}
  $ps | grep -v $psl | grep $command
done

${var:1} は変数 $var から文字を切り出す bash の組み込み機能。${変数名:切り取り開始:切り取り終了} という書式。開始位置は 0 から数える。「切り取り終了」は省略可能。つまり、$var=foo なら ${var:1}oo を返す。${var:0:1} なら、f を返す。