20200817のLinuxに関する記事は7件です。

【bash】におけるクォートの扱い

背景

bashを書き始めたばかりの新米エンジニアです。コーディングしていて、
”あれ、ここシングルクォート?ダブル?そもそも囲う必要あるのかな?まぁ動けばなんでもいいか・・・”
という具合にいつも悩んでしまうので、改めて整理することにした。

結論

以下の認識でOK。
詳しくは個別に後で解説する。
コメント 2020-08-17 221526.png

シングルクォート''

文字列をシングルクォートで囲むと、文字列中の各文字すべてが特殊な意味を失い、文字通りの意味として解釈される。

# $HOMEはシェルを実行中のユーザのホームディレクトリが設定されている特別なシェル変数

$ echo '$HOME' # シングルクォートで囲む
$HOME # そのまま$HOMEと出力される

$ echo "$HOME" # ダブルクォートで囲む
/c/Users/guest.name # シェル変数の値に展開される

$ echo '*' # シングルクォートで囲む
* # そのまま*と出力される

$ echo * # 何もクォートしない
bin doc src # カレントディレクリのファイル名に展開される

ダブルクォート""

文字列をダブルクォートで囲むと、シングルクォートとほぼ同様にほとんどの文字がその特殊な意味を失う。
しかし、\$と`の特殊な意味は残るため、パラメータ展開とコマンド置換は行われる。
予期せぬ挙動を防ぐために、"\$変数" や "\$(コマンド置換)" はダブルクォートで囲んだほうが良さそう。

# パラメータ展開
$ var='*** hello  world ***' # スペースの連続と*を含む文字列

$ echo "$var" # ダブルクォートで囲む
*** hello  world *** # 正しく表示される

$ echo $var # ダブルクォートで囲まない
bin doc src hello world bin doc src # スペースが区切り文字として解釈され、前後にカレントディレクトリのファイル名が展開される

# コマンド置換
$ user='$(whoami)' # シングルクォートで囲む
$ echo "$user"
$(whoami) # 単なる文字列として解釈されている

$ user="$(whoami)" # ダブルクォートで囲む
$ echo "$user"
guest.name # whoamiコマンドの結果が代入されている

バックスラッシュ\

文字の前にバックスラッシュををつけると、\の直後の1文字が特殊な意味を失い、文字通りの意味として解釈される。

$ echo \$HOME  # $の前にバックスラッシュをつける
$HOME # そのまま$HOMEと出力される

$ echo $HOME # バックスラッシュをつけないと
/c/Users/guest.name # シェル変数の値に展開される

$ echo \*  # *の前にバックスラッシュをつける
*  # そのまま*と出力される

$ echo *  # バックスラッシュをつけないと
bin doc src  # カレントディレクリのファイル名に展開される

参考文献:山森 丈範 『[改訂第3版]シェルスクリプト基本リファレンス ──#!/bin/shで、ここまでできる』 技術評論社 (2018/11/14)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【bash】におけるクォートの使い分け

背景

bashを書き始めたばかりで使い分けに迷ったので、改めて整理することにした。
初心者の方は参考にしてください。

結論

基本的には以下の認識
コメント 2020-08-17 221526.png

シングルクォート''

囲われた文字すべてが特殊な意味を失います。

業務ではファイルにヘッダーをつける時など、単純な文字列を出力したい時に使っています。

echo 'colomn1 column2 column3' > file1

以下サンプル

# $HOMEはシェルを実行中のユーザのホームディレクトリが設定されている特別なシェル変数

$ echo '$HOME' # シングルクォートで囲む
$HOME # そのまま$HOMEと出力される

$ echo "$HOME" # ダブルクォートで囲む
/c/Users/guest.name # シェル変数の値に展開される

$ echo '*' # シングルクォートで囲む
* # そのまま*と出力される

$ echo * # 何もクォートしない
bin doc src # カレントディレクリのファイル名に展開される

ダブルクォート""

パラメータ展開、コマンド置換を行う時につけるものと解釈して良さそう。
アスタリスク(*)やスペース( )といった、特殊な文字が解釈されて予期せぬ挙動を引き起こすことがあるのでつけたほうが良いらしい。

testコマンドの判定に変数を使ったり

[ -z "$var" ] # 変数$varが空かどうかを判定する条件式

コマンド置換でファイルリストを取得したりする際に使っています。

file_list="$(ls /home/data/*.csv)"

以下サンプル

# パラメータ展開
$ var='*** hello  world ***' # スペースの連続と*を含む文字列

$ echo "$var" # ダブルクォートで囲む
*** hello  world *** # 正しく表示される

$ echo $var # ダブルクォートで囲まない
bin doc src hello world bin doc src # スペースが区切り文字として解釈され、前後にカレントディレクトリのファイル名が展開される

# コマンド置換
$ user='$(whoami)' # シングルクォートで囲む
$ echo "$user"
$(whoami) # 単なる文字列として解釈されている

$ user="$(whoami)" # ダブルクォートで囲む
$ echo "$user"
guest.name # whoamiコマンドの結果が代入されている

バックスラッシュ\

文字の前にバックスラッシュををつけると、\の直後の1文字が特殊な意味を失い、文字通りの意味として解釈される。

$ echo \$HOME  # $の前にバックスラッシュをつける
$HOME # そのまま$HOMEと出力される

$ echo $HOME # バックスラッシュをつけないと
/c/Users/guest.name # シェル変数の値に展開される

$ echo \*  # *の前にバックスラッシュをつける
*  # そのまま*と出力される

$ echo *  # バックスラッシュをつけないと
bin doc src  # カレントディレクリのファイル名に展開される

参考文献:山森 丈範 『[改訂第3版]シェルスクリプト基本リファレンス ──#!/bin/shで、ここまでできる』 技術評論社 (2018/11/14)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LinuxのVLCの回転ができなくなったときの対処

Preferences -> Input/Codecs -> Disable hw decoding

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Parallels Desktop 16 for Mac で CentOS 7 を目立たないようにコマンド起動

Macユーザーですが、Windows 10 も顧客のサポートのために必要なことがあるので、 Parallels Desktop は導入済みでした。

一方、MacでLinuxのアプリ開発において使うような imagemagik だとか、Vue.js とか、もっと言えば rbenv なんかでさえも、 「Macの環境を汚すのでインストールしたくない!」 という説明しがたい感情がありました。

そこで、Parallels Desktopに、CentOS 7 を導入して、そのVMボリューム(ファイル)の中でこういった「汚い?」ことは完結させることにしました。

Parallels Desktopでの CentOS 7の導入自体の説明は省きますが、それをコマンド起動したり、Parallelsのアプリのウィンドウを表示しなくしたりといった設定を以下にまとめます。※Parallels Desktop 16の現時点です。

ParallelsでCentOS 7 をインストールが終わると、 Parallels というユーザーがデフォルトで作られ、GNOME が起動し、Parallels パスワードを設定してくださいという画面になりパスワードを決めて入力します。そこまでは、とりあえず終えているとします。

Macターミナルからのssh接続

Paralells では、CentOSを起動中、Macの/etc/hosts に、自動的に以下が追加されるようです。(10.XXX.XX.X の部分はParalellsが自動で決めたVMのIPアドレスです)

10.XXX.XX.X     centos7.shared centos7 #prl_hostonly shared

ですので、Macのターミナルアプリから

% ssh paralells@centos7
parallels@centos7's password: 

で接続できます。パスワードは、最初に設定したパスワードです。
ParalellsのCentOSを終了すると、/etc/host は自動的に元に戻るようです。

Dockerなどは root でインストールしたい

parallelsユーザーは、wheelを付加されているのでsudoが使えるのですが、いっそ、rootユーザーになってしまった方が楽ちんです。そこで、rootのパスワードも変えてしまします。
parallelsユーザーで sudosu - して root になって、passwd します。

[parallels@centos7 ~]$ groups $USER
parallels : parallels wheel
[parallels@centos7 ~]$ sudo su -
[sudo] parallels のパスワード:
最終ログイン: 2020/08/17 (月) 15:31:06 JST日時 pts/0
[root@centos7 ~]# passwd
Changing password for user root.
New password: 
Retype new password: 
passwd: all authentication tokens updated successfully.
[root@centos7 ~]#

これで、Macのターミナルから、

% ssh root@centos7 
root@centos7's password: 

でログインできるようになり、
Docker や git、環境に必要なライブラリをrootでインストールできます。

さらに、僕は開発用のユーザーを追加して、普段はこちらでログインして使うことにしています。

[root@centos7 ~]# useradd development

/home/development ディレクトリを開発専用にします。(ParalellsユーザはGNOMEログインしてしまっているので、Desktop, Documentsといった不要なディレクトリがあるので、GNOMEログインしないユーザとしてdevelopmentを設置)

VMをコマンド起動したい

Parallelsのアプリをいちいち起動するのではなく、VM毎にコマンド起動するには

% prlctl start <VMの名前>

で起動できます。CentOS 7のデフォルトのVM名は CentOS 7 なので、起動コマンドを簡単にするために、VMの設定で名前を変更しておきます。例えば centos7 としておけば少し楽です。
fig.png

各コマンドは以下のようです(説明省力)。

% prlctl start centos7
% prlctl stop centos7
% prlctl restart centos7
% prlctl pause centos7
% prlctl resume centos7
% prlctl list --all

Parallelsのウィンドウは要らない

CentOSでコマンドしか使わないのであれば、Paralellsのウィンドウも不要です。
表示しない設定がちゃんとありました。

% prlctl set centos7 --on-window-close keep-running

まとめ

以上の設定をすれば、
Macのターミナルアプリから、VMの起動から、開発作業、終了まで一連のことがコマンドだけでできるようになります。

% prlctl start centos7
Starting the VM...
The VM has been successfully started.
% ssh development@centos7
development@centos7's password: 
Last login: Mon Aug 17 15:30:51 2020 from 10.211.55.2
[development@centos7 ~]$ 
……
…… <CentOS上で開発など> ……
……
[development@centos7 ~]$ exit
ログアウト
Connection to centos7 closed.
% prlctl stop centos7    
Stopping the VM...
The VM has been successfully stopped.
% 

Paralellsのウィンドウが表示されることもなく、「静かに?」仕事ができます。

注意点は、startからsshログインできるまでに、当然起動のためのタイムラグが少しあることと(すぐにはsshできない)、 stop することを忘れないこと(使わないならCPUとメモリ資源のムダ)。

なお、Macのファイルは /media/psf 以下にあります。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

gpgでHTTP fetch errorが出て鍵が取得できないエラーの対処

TL;DR

  • hkpのポートは通常11371
  • gpg --keyserver hkp://keyserver.ubuntu.com:80 のように利用出来るポートを指定するといい

状況

社内仮想ホスト上のcentos7にpritunlをインストールしようとした際、下記のようなエラーが出ました

$ gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys CF8E292A
gpg: 鍵CF8E292Aをhkpからサーバkeyserver.ubuntu.comに要求
gpgkeys: HTTP fetch error 56: Recv failure: Connection reset by peer
gpg: 有効なOpenPGPデータが見つかりません。

hkpのポートは通常11371を利用します。今回利用した仮想ホストはセキュリティ設定によりアウトバウンドの11371が許可されていなかった為エラーになっていました。

$ cat /etc/services | grep hkp
pgpkeyserver    11371/tcp       hkp             # PGP/GPG public keyserver
pgpkeyserver    11371/udp       hkp             # PGP/GPG public keyserver

yum出来る環境であれば80番等使えると思うので、:80を指定。

$ gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys CF8E292A
gpg: 鍵CF8E292Aをhkpからサーバkeyserver.ubuntu.comに要求
gpg: 鍵CF8E292A: 公開鍵"Pritunl <contact@pritunl.com>"をインポートしました
gpg:         処理数の合計: 1
gpg:           インポート: 1  (RSA: 1)

上手くいきました

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RedHat 設定確認コマンド

確認コマンド.log
fdisk -l
df -hT
swapon -s
cat /etc/fstab
hostnamectl status
systemctl list-unit-files -t service | cat
cat /etc/group 
cat /etc/passwd
#/etc/sysconfig/network-scripts/eth0
nmcli device show | cat
grep PermitRootLogin /etc/ssh/sshd_config
grep AllowUsers /etc/ssh/sshd_config 
firewall-cmd --get-active-zones
firewall-cmd --list-all --permanent
firewall-cmd --list-ports --zone=public --permanent


cat /etc/redhat-release
uname -a
localectl status
df -hT
swapon
hostname
cat /etc/hosts
ip addr
ip route
timedatectl status | grep Tokyo
getenforce
systemctl status kdump.service
systemctl status sendmail.service
systemctl status postfix.service
systemctl status dovecot
systemctl status httpd
systemctl status postgresql-server
systemctl list-unit-files | grep kdump
systemctl list-unit-files | grep sendmail
systemctl list-unit-files | grep postfix
systemctl list-unit-files | grep dovecot
systemctl list-unit-files | grep httpd
systemctl list-unit-files | grep postgresql-server
systemctl list-unit-files | grep chronyd
grep server /etc/chrony.conf
cat /etc/resolv.conf
who -r


systemctl list-unit-files -t service | cat
yum list installed 
netstat -auntpl



  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

all arch: remove system call sys_sysctl

カーネルのcommit logを見てたら、全アーキテクチャに関わる修正があった。なんだろうこれ?というメモ。

TL;DR:ある機能を削除する事は難しい

これ、最初の段階からすると、10年がかりですね。本当に関係者の方々、ありがとうございます、お疲れ様でした。

時系列に並べていくと…

[PATCH] sysctl: Allow /proc/sys without sys_sysctl ( 2006/09/27 )

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/kernel/sysctl.c?id=b89a81712f486e4f7a606987413e387605fdeaf4

Since sys_sysctl is deprecated start allow it to be compiled out. This should catch any remaining user space code that cares, and paves the way
for further sysctl cleanups.

sys_sysctlは廃止予定なので、コンパイル対象外にし始めます。残りのユーザー空間コードをキャッチし、更なるsysctlクリーンアップに向けて道を開くはずです。

sysctl: Separate the binary sysctl logic into it's own file. ( 2006/11/06)

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=61a47c1ad3a4dc

In preparation for more invasive cleanups separate the core binary sysctl logic into it's own file.

より侵略的なクリーンアップに向けて、core binary sysctl logicを独自のファイルへ分離します。

sysctl: Remove the sysctl system call ( 2019/11/26 )

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=61a47c1ad3a4dc

This system call has been deprecated almost since it was introduced, and in a survey of the linux distributions I can no longer find any of them that enable CONFIG_SYSCTL_SYSCALL. The only indication that I can find that anyone might care is that a few of the defconfigs in the kernel enable CONFIG_SYSCTL_SYSCALL. However this appears in only 31 of 414 defconfigs in the kernel, so I suspect this symbols presence is simply because it is harmless to include rather than because it is necessary.

As there appear to be no users of the sysctl system call, remove the code. As this removes one of the few uses of the internal kernel mount of proc I hope this allows for even more simplifications of the proc filesystem.

このsystem callは導入された時点から非推奨であり、Linuxディストリビューションの調査では、CONFIG_SYSCTL_SYSCALLを有効にするディストリビューションはもう見つかりません。これに対して気に掛ける誰がいるかどうかを検出する唯一の方法は、カーネル内のいくつかのdefconfigでCONFIG_SYSCTL_SYSCALLを有効にすることです。ただし、これはカーネルのdefconfigの414中31にしか現れません。そのため、私はこのシンボルの存在は、必要ではなく、含まれても無害と考えます。

sysctl system callのユーザーがいないように見えるため、このコードを削除します。procの内部カーネルマウントの数少ない使用方法が削除されます。proc filesystemが更に単純化されることを期待しています。

all arch: remove system call sys_sysctl (2020/08/16 )

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=88db0aa2421666d2f73486d15b239a4521983d55

all arch: remove system call sys_sysctl
Since commit 61a47c1ad3a4dc ("sysctl: Remove the sysctl system call"), sys_sysctl is actually unavailable: any input can only return an error.

We have been warning about people using the sysctl system call for years and believe there are no more users. Even if there are users of this interface if they have not complained or fixed their code by now they probably are not going to, so there is no point in warning them any longer.

So completely remove sys_sysctl on all architectures.

all arch: system call sys_sysctlを削除する。
commit 61a47c1ad3a4dc ("sysctl: Remove the sysctl system call")以来、sys_sysctl は実質無効であった: 入力に関わらずエラーを返す。

sysctl system callを利用するユーザーに対して長年警告を続け、更なるユーザーはいないものと確信した。このインターフェイスを使用しているユーザーがいても、コードに対する不満や修正をしていない場合は、おそらくそうするつもりはないはずであり、警告する意味はもう無い。
そこで、sys_sysctlを全アーキテクチャで完全に削除します。

結論:ある機能を削除する事は難しい

これ、最初の段階からすると、10年がかりですね。本当に関係者の方々、ありがとうございます、お疲れ様でした。

  • 2009/09/27 deprecate予定なので、コンパイル対象外にできるようにコンフィグレーションに追加。
  • 2009/11/06 機能をクリーンアップのために分離。この時点でdeprecated.
  • 2019/11/26 削除するための機能無効化
  • 2020/08/16 機能完全削除

「本当にこのコードを消していいのか?」をどうやって確定させるのか、ということを含めて、難しいものだなあと考えさせられました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む