Linuxの便利なTIPS (up-to-date)

デスクトップ利用

KDE Plasmaで等幅フォントが上手く表示されない、選択できない

日本語では「等幅フォント」と呼んでいますが、英語では “monospace” フォントであり、これは「単一空間のフォント」ということになります。 しかし、実際には「等幅日本語フォント」には1文字幅と2文字幅の2種類が存在し、 “dualspace” フォントとなっています。

これはフォントにspacingという値があり、monospaceの場合100, dualspaceの場合は90となります。 Qtはmonospaceフォントのリストとして>= 100を条件にしているため、等幅日本語フォントがリストされないという状態になります。

最も簡単な方法は~/.config/fontconfig/fonts.confmonospaceを定義し、monospaceを指定する方法です。

<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
  <match target="pattern">
    <test qual="any" name="family">
      <string>monospace</string>
    </test>
    <edit binding="strong" name="family" mode="assign">
      <string>Migu 1M</string>
    </edit>
  </match>
</fontconfig>

fonts.conf内でのspacingの設定はフォントのリストには影響しません (そもそもフォントを一覧する段階ではfonts.confの置換えは考慮されません)。 これを利用して既存のmonospaceフォントで使用しないものがあれば、それを置換えてしまう方法もあります。

<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
  <match target="pattern">
    <test qual="any" name="family">
      <string>DejaVu Sans Mono</string>
    </test>
    <edit binding="strong" name="family" mode="assign">
      <string>Migu 1M</string>
    </edit>
  </match>
</fontconfig>

Plasma Workspaceのactivityがよくわからない

ActivityはそもそもPlasma Workspace 4で導入された概念であり、デスクトップモードやウィジット同様Plasma5ではなかったことにされたもののひとつです。 Plasma4では作業パターンに合わせてactivityを設定することが推奨されていましたが、実際のところ面倒であるため誰もそのようにせず、使われないためにPlasma5では存在感を減らしました。

activityの用途として大きなものは一部設定がactivityによって分離できることにあります。 特に電源管理を独自に設定できるため、ラップトップにおいては「プレゼンテーションモード」のactivityを作っておくと便利です。

連動して壁紙も変わります。

ウィンドウセットを保存したい

複数のウィンドウの配置を保存したい場合、ワークスペースが便利です。 近年はあまり使われなくなりましたが、昔はディスプレイが小さく、マルチディスプレイも難しかったため「巨大な画面の一部に着目する」という感覚でワークスペースが利用されていました。

例えばFirefoxとEvinceとAtomを開き、FirefoxまたはEvinceを見ながらAtomを使う、という場合、 ウィンドウタイリングを使用してFirefoxとEvinceを同じサイドに、Atomを別のサイドに配置します。

これをワークスペース1に配置したら、メールのような対話的操作が必要で、別系統となる作業をワークスペース2に配置することで切り替えながら状態を変遷させることができます。

デスクトップ環境にもよりますが、特にマルチディスプレイ環境ではウィンドウが常時表示させておきたいようなケースもあります。 これは「すべてのワークスペースに表示」や「最前面に表示」を活用してください。

ウィンドウセットをセッションを越えて保存したい場合はデスクトップセッションの保存機能を利用してください。 また、ウィンドウの内容まで維持したい場合はシャットダウンせずにサスペンドするようにしてください。

動画を画面上に小さく表示しておきたい

YouTubeのウィンドウ再生モードのようなことをしたい場合です。

mpvを使いましょう。

mpv --autofit=300x200 --no-border --ontop --ontop-level=window --geometory=100%:100% file

Fcitxでインラインエディットとプレエディットを切り替える

インラインエディットはアプリケーション内に文字を入力した上で編集を行い、プレエディットはIME側で編集を行って確定した文字列をアプリケーションに送信します。

通常、インラインエディットが可能な場合はインラインエディットを行い、できない場合はプレエディットを行います。 インラインエディットが可能かどうかはIMEとアプリケーションの組み合わせによります。

ただし、インラインエディットが可能でもプレエディットしたい場合があります。 主にインラインエディットによって不具合が発生する場合です。 たとえば編集状態が維持できないなどアプリケーションがインラインエディットを阻害する場合などです。

Fcitxの場合、標準でCtrl+Alt+Pによってプレエディットを切り替えることが出来ます。 これはfcitx-conftoolにおいてはAdvanced Settings内にあります。

インラインエディットを無効にした場合でもIMEの問題が解決しない場合もあります。 これは主にアプリケーション側がキーイベント拾ってしまうためにIMEの動作に介入されてしまうケースです。

エディタにパイプで入力した内容を開く

Vimが可能です。 また、Leafpadもできますが、あまり安定していません。うまく入力されないことがあります。

また、Kwriteはkwrite -iとすることで標準入力から受け取ることができます。

パイプでエディタを開きたい理由がコピーアンドペーストのためならxselに渡すのも良いでしょう。

あるいは読むだけであればlessなどに渡すという方法もあります。

これのいずれも要件を満たさないのであれば、/tmpなどの一時ディレクトリに内容を保存しましょう。

あるいはその目的が別のファイルのある部分に挿入することにあるのであれば、例えば次のような方法があります。 まず、ファイルとして保存し(挿入対象のドキュメントと同一ディレクトリか、もしくはパスの指定しやすい場所が良いでしょう。/tmp以下は有力です)、その上で対象のドキュメントをVimで開きます。 そして挿入したい箇所に移動したら:r path/to/fileとすれば目的を完了できます。あとは:wqで終了すれば良いでしょう。 Vimならば:r! commandの形でそもそもコマンド実行結果に置き換えることもできます。

目的がファイル末尾に追加することであるならば単純に追記リダイレクト(>>)で済みます。

HID

タッチパッドでサーキュラースクローリングを使う

タッチパッド上で円を描くことでスクロールできる機能です。

現在はlibinputを使うことが主流となっており、Synapticsドライバは既にobsolateであるために積極的にlibinputに移行しているのですが、サーキュラーすクローリングはlibinputで実装されていません。Synapticsを使い、/etc/X11/xorg.conf.d/以下に設定ファイルを配置します。

Section "InputClass"
    Option      "CircularScrolling"          "on"
    Option      "CircScrollTrigger"          "0"
EndSection

ユーザー

rootとしてファイルを編集したい

単純には

sudo vim file

のようにすれば良いのですが、これが適さないケースもあります。 例えばKwrite/Kateはsudoによって呼ばれることを許容しません。

このような場合、sudo -e fileとすることでファイルをrootとして編集することができます。 (あるいは、sudo -e -u user fileとして任意のユーザーとしてファイルを編集することもできます)

このとき使用されるエディタ$EDITORに従います。 ですから、

EDITOR=kwrite sudo -e file

とすることで一時的にKwriteを使うようなこともできますし、あるいは$EDITOR~/.profileで設定しておいても構いません。

ディレクトリを755、通常ファイルを644、実行ファイルを666のパーミッションにしたい

umaskの値が077になっていた場合や、アーカイブの展開時などで意図せずディレクトリが700、ファイルが600になってしまい、困ることがあります。 もちろん、findと組み合わせたり、Zshのグロブを使う方法もありますが、面倒ですし、あまり美しくありません。

このような問題はよくあるものであり、専用のパーミッションXが用意されています。 これは、ディレクトリ、及び既に実行フラグがあるファイルに実行フラグを立て、そうでない場合は立てません。 多くの場合これは理想的な動作です。

これにより

sudo chmod -R go+rX directory

とすれば解決します。

grepでAND検索やOR検索をしたい

OR検索をする場合は-eオプションを並べるだけです。 拡張正規表現やPCREで行うよりも確実で高速です

grep -F -e "foo" -e "bar" -e "baz"

AND検索する場合はパイプを使うのが通常の流儀です。

grep "ptn1" | grep "ptn2"

しかし-lオプションを使いたいような場合はそうもいきません。

まずはPerlを使う方法

find -print0 path/to/target -type f | xargs -0 -- perl -e 'local $/;' -e 'foreach $fn (@argv) { open(FH, "<$fn"); <FH>; print $fn if /ptn1/ && /ptn2/; close(FH) }'

Rubyだともっと簡単に書けます。

find -print0 path/to/target -type f | xargs -0 -- ruby -e 'puts ARGV.select {|fn| /ptn1/.match? fn && /ptn2/.match? fn}'

しかしこのケースにおいては条件が多くならない限りgrepのほうが楽です。

grep -l ptn1 | xargs -d $'\n' -- grep -l ptn2

コマンドラインとシェル

正規表現に一致する部分を抜き出したい

grepで済むのであれば-oオプションが使えます。

grep -o regex file

キャプチャも必要になる場合はPerlが良いでしょう。

perl -n -e 'while(/re(ge)x/g) { print $1, "\n";}'

複数ファイルに対して処理を適用したい

tar, unzipsed -iなど単一ファイルに対して処理をするコマンドを複数のファイルに対して適用するには、forを使います。

for i in *.zip; do unzip "$i"; done

unzipの場合はアーカイブと同じ名前のディレクトリに展開するようにしたほうがいいかもしれません。

for i in *.zip; do unzip -d "${i%.zip}" "$i"; done

端末を閉じたときに実行を継続したい

nohupを使う方法やshopt -u huponexit(Bash)あるいはsetopt NOHUP(Zsh)する方法もありますが、 これはSIGHUPを有効に使うプロセス(例えばConky)では困ってしまいます (実際はそれほど困りませんが)。

Bash及びZshにはdisownというコマンドがあり、これによりジョブテーブルからジョブを削除し、SIGHUPを送信する対象外にすることができます。

disownするときはジョブは停止中ではなくバックグラウンドでの実行中に行うようにしてください。 Zshではsetopt AUTO_CONTINUEしておけば自動的に停止中のジョブをdisownした場合にSIGCONTを送信します。

また、Zshではジョブを&|または&;で開始することで最初からジョブテーブルから削除した状態で開始できます。

デスクトップに通知を表示したい

最も簡単なのはnotify-sendを使用する方法です。

notify-send Hello

ZenityやKdialogでも可能です。

zenity --notification --text=Hello
kdialog --passivipopup Hello

Yadの--notificationオプションはsystrayを使うためのオプションであり、Yadでは利用できません。

シェルスクリプトで部分的に一般ユーザーで実行したい

initやcronから呼ばれるようなスクリプトで全体的にはシステムレベルで動作するものの、部分的にユーザーレベルで動作する(例えば通知など)ということがあります。 rootで実行しても良いのですが、デーモン型の動作をする場合は望ましくありませんし、そうでなくとも危険でもあります。

Bashの場合は$EUIDが読み取り専用なのですが、Zshであれば$EUIDに書き込むことができ、rootで実行されているスクリプトから他のユーザーとして部分的に実行することができます。

このような場合、その部分をサブシェルで実行するのが良いでしょう。

#!/bin/zsh

# ここはrootで実行されている

proc1
proc2
#...

(
  EUID=$(id -u jrh) #ユーザーjrhとして実行する
  userproc1
  userproc2
  #...
)

GUIアプリケーションを使う場合、このスクリプト自体を実行するタイミングでsudo -Esudo --preserve-env=XAUTHORITYとして環境変数を維持する必要があります。 スクリプトがユーザーによってではなくシステムによって(例えばSystemdから)起動される場合はスクリプトを分離してsudo -u userとするほうが良いでしょう。

デスクトップ通知を使用する場合はDBusを使うためこれではうまくいきません。 最も簡単な方法として表示が異なりますが、kdialog --passivepopupを使えば(表示スタイルは異なるものの)表示させることができます。 あるいはsudoを使う場合にDBusのbusを設定すれば通知することができます。

sudo -u jrh DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u jrh)/bus notify-send Hello

環境変数はsudoに対してではなく、sudoが実行するコマンドに対して設定しなくてはいけません。 ですから

DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u jrh)/bus sudo -u jrh notify-send Hello

では失敗します。

複合的、あるいは複雑なクォートを必要とするスクリプトをsudoによって実行させたい場合、sudoにシェル関数を渡すことはできないので、 bash -szsh -s を渡し、ヒアドキュメントを使うと良いでしょう。

sudo -u jrh bash -s <<USER_SCRIPT
export DISPLAY=:0
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u jrh)/bus
yad --notification --command="notify-send Hello" --image=call-start
USER_SCRIPT

バイナリを出力して端末がおかしくなった

端末を開き直すというのが簡単な方法ですが、resetコマンドをつかうか、echo ^[c(^[cはCtrl+V Ctrl+C)を入力すると良いでしょう。

コマンドラインからコピーアンドペーストをしたい

xselはセレクション(マウスのボタン3クリックでペーストするもの)及びクリップボード(右クリックメニューやCtrl+Vでペーストするもの)を扱うことができます。

X.Orgのコンポーネントですが、最近のディストリビューションはxselが標準で導入されないことが多いため、インストールの必要があるかもしれません。

セレクションへコピーするにはxselを使います。

$ ls | xsel

クリップボードへのコピーはxsel -bを使います。

$ xsel -b < foo.file

xsel -oでセレクションを出力することができます。xsel -b -oとしてクリップボードの出力も可能です。

$ xsel -bo | less

xselはWayland環境では利用できません。 Waylandではwl-clipboardが利用できます。

daily hack

決まった文字列(スニペット、定型文)を簡単に打ちたい

改行を含まない文字列を素早く打つにはFcitx quickphraseが便利です。

Fcitxの設定でアドオンとしてquickphraseを有効にし、フレーズリストを編集しましょう。 これでFcitxを使って(編集モードをオンにしていなくても)Ctrl+@をタイプすることで素早く文字列を打つことができます

複数行に渡る文字列を入力したい場合はクリップボードツールを使うのが良いでしょう。 各デスクトップ環境に適したクリップボードツールがあるはずですが、必ずしも定型文を打つのに適した機能があるとは限りません。

もし必要ならばcopyqなどその他のクリップボードツールを使うと良いでしょう。

ネットワーク

SSHでホスト名やオプションが長い

履歴を使う方法もありますが、~/.ssh/configに記述しておくことでだいぶ楽になります。 HostはSSHでログインするときにリモートホスト名に対してパターンマッチングを行いますが、HostNameの値はこれは別に設定することができます。 そのため、Hostは実際にその名前で到達できるリモートホストである必要はなく、好きなホスト名をつけることができます。

~/.ssh/configに記述しておくことにより、ユーザーや使用する鍵ファイルなども指定することができるため、コマンドラインのミスが少なくなります。 また、Nautilus, Nemo, ThunarといったファイルマネージャでSFTPアクセスを行う際にも有用です。

Host foohost
  User jrh
  HostName 123f98e6729ca90e.very.very.long.hostname.example.com
  Port 2222
  IdentityFile ~/.ssh/verylong-example-com_rsa
  IdentitiesOnly yes

Windowsとの共生

Zipファイルが文字化けする

unzipによってZipアーカイブ内のファイル名が文字化けする場合、日本語ファイルであればファイル名がCP932になっているためである可能性が高いでしょう。

このような場合は

unzip -O cp932 archive.zip

とすることで解消できます。

実際に遭遇したことはありませんが、WindowsネイティブなUTF-16BEを要求されるかもしれません。

このzip/unzipの機能はiconvを利用しており、iconv -lによってサポートされている文字エンコーディングを知ることができます。

UTF-8で書かれていないテキストファイルを読みたい

コマンドラインから指定するのであればGeditやw3mも使えます。 ここでは非日本語の文字エンコーディングの判別はあまり考えていないため、そのような場合は指定したほうが良いかもしれません。

Leafpadを使う

Leafpadには日本語文字エンコーディングの自動判別機能があります。 派生のMousepadにはない機能です。

lvを使う

lvはlessのようなページャです。 Leafpadよりも判定能力に優れています。

vimを使う

~/.vimrc

set fileencodings=utf-8,sjis,euc-jp,iso-2022-jp

としておくことでvim -R fileで自動判別してくれます。

エマージェンシー

rootパスワードを忘れた

sudoerであるならば、

sudo passwd

で再設定ができます。

システムが起動できなくなった

理由が様々なので簡単には言えないのですが、アップデート、アップグレード時にブートイメージが破損することが時にはあります。 それ以外にもブートイメージの破損、起動に必要な設定ファイルの記述ミスなど様々な理由で起動不能になることは稀にあります。

このような場合、fallback shell(レスキューモード)に落ちるのであればコンソールから問題を解消できることもありますが、 fallback shellにまで到達できないような場合もありますし、場合によっては(特に多くの場合sudo bash -lのような形でroot権限を使っているような場合は)rootパスワードがわからずfallback shellからでは作業できないという場合も多いでしょう。

まず、非常によくある重要なこととして、 NTFSはWindowsがロックする場合があり、Linuxからはこの状態でRWでマウントできません 。当然、RWでマウントしようとすると失敗するのですが、 /etc/fstabによる自動マウントが行われる場合、失敗するとSystemdは起動自体を失敗とみなします。 これはautoなファイルシステムはlocal-fs.targetRequiresに入るためです。 nofailオプションをつければファイルシステムの.mountユニットはWantsに入ることになり、この問題が解消されます。 ですから、NTFSを起動時にRWでマウントしたい場合、nofailオプションをつけるのが妥当でしょう。

ただし、実際のところ必要であればmount -o remount,rwする前提で読み取り専用でマウントしておくか、あるいは現代的なデスクトップ環境によるマウント機能を使うことを前提としてシステム的にマウントしないでおく運用を考えるほうが好ましいと思われます。

さて、原因は見当がつくものの起動できないため修復できないとしましょう。

この場合、まずなるべく近似の環境でライブブートします。 デスクトップ環境が使えるほうが便利ではありますが、必ずしも必須ではありません。 openSUSEを使っている場合など近似の環境でライブブートできない場合でも、インストールディスクを起動し、インストーラが起動してからCtrl+Alt+F2を押してコンソールに移れば作業できる場合もあります。

ライブブートした環境でrootでシェルを開きます。 そして作業ディレクトリにターゲットシステムのルートファイルシステムをマウントします。

# mount /dev/sda3 /mnt

ルートファイルシステムがLUKSで保護されている場合はこれを解除します。

# cryptsetup luksOpen /dev/sda3 rescueroot
# mount /dev/mapper/rescueroot /mnt

必要な仮想ファイルシステムを作業ディレクトリ以下にバインドマウントします。 一般的には/dev, /proc, /sysです。

# mount --rbind /dev /mnt/dev
# mount --rbind /proc /mnt/proc
# mount --rbind /sys /mnt/sys

/bootが別に分かれている場合はそれもマウントします。 また、UEFIシステムではESPもマウントしなければなりません。これは/bootが分けられているかどうかは関係ありません。 ESPはディスクがLinux専用になっているのであれば通常はディスクの最初のパーティションで、FAT32でフォーマットされた512MBのファイルシステムです。 Windowsとデュアルブートしているのであれば、Windowsと共有されている可能性があります。

# mount /dev/sda2 /mnt/boot
# mount /dev/sda1 /mnt/boot/efi

ESPは一般的に/boot/efiですが、必ずそうであるとはいい切れません。 Grubのインストールオプションとして指定できるため、ディストーションによるこだわりの場所がある可能性もあります。

準備ができました。それではログインしましょう。

# chroot /mnt

これでシステムのシェルにrootでログインしたのとほぼ同じ状態になります。 必要な修復を行いましょう。

Grubのアップデートに失敗した場合はManjaro Linuxでは次のようにします。

# update-grub

Arch Linuxにはこのようなツールがないため、直接指定します。

# grub-mkconfig -o /boot/grub/grub.cfg

実際のところ両者の違いはこれが全てです。 Manjaroのupdate-grubの中身は

#! /bin/sh
grub-mkconfig -o /boot/grub/grub.cfg

であるためです。

ブートイメージ自体が破損した場合、普通はfallback imageから起動できますし、fallback image自体起動できなくなっている場合はそのままでは起動できない可能性が高く、イメージの再生成はせずに問題を修正(例えばディスクの交換)をしたほうが良いでしょう。 ただし、イメージの再生成が問題を解決すると考えられるのであれば

# mkinitcpio -p linux

のようにすればブートイメージを生成できます。 これはカーネルがlinuxの場合です。Linux Zenカーネルを使っている場合はlinux-zenになりますし、Manjaroの場合はlinux419のようにmhwd-kernelと同じバージョンの指定になります。あるいはmkinitcpio -Pとすることでインストールされた全てのカーネルイメージを生成できます。

原因の究明が必要な場合はよりスキルを必要とします。

«