ひゃまだのblog

ひゃまだ(id:hymd3a)の趣味のブログ

Bashのプロセス置換のメリットを考えてみた

(2024-05-21 初稿)

Bashには、プロセス置換という便利な機能があるが、ちょっと使い方やそのメリットがわかりにくかったので、そのメリットについていくつかの例を考えてみた。

今回の記事は、以下のサイトを参考にさせて頂いた。多謝。m(__)m

プロセス置換の説明として、下のリンクの「ファイルを記述する替わりに、その位置にプロセス(コマンド)を記述」がわかりやすいかと思う。

プロセス置換は大きく分けて、2つのメリットがあると思われる。

  • 一時ファイルが不要となる
  • パイプを利用しないので、サブシェルの罠にはまらない

一時ファイルが不要となる

処理をしてから比較する

普通にdiffコマンドで比較する場合には利用価値は無いが、何らかの処理をしてから比較する場合は一時ファイルが不要となるためメリットがある。

具体例として、以下の2つの例をあげる。

大文字に変換(trコマンド)してから比較する

diff <(cat a.txt | tr a-z A-Z) <(cat b.txt | tr a-z A-Z)
grep SOMEWORD <(cat test.txt | tr a-z A-Z)

リモートのファイルと比較する

筆者が考えた最大のメリットは、ssh等でリモートファイルを扱う場合。

remote-pcには、sshでアクセスできるように設定する必要があるけど。

diff /etc/hosts <(ssh remote-pc cat /etc/hosts)
grep someword <(ssh remote-pc cat test.txt)

パイプを使用しないので、サブシェルの罠にはまらない

ちょっと前に以下の記事に書いたが、パイプを利用しないのでサブシェルの罠にはまらずに済む。

前述の例は、パイプを使った場合以下のように書ける。

grep SOMEWORD <(cat test.txt | tr a-z A-Z)
       ⇓
cat test.txt | tr a-z A-Z | grep SOMEWORD

ただし、以下のようなスクリプトの場合、パイプを使うとGVarの値が変わらず、意図したものと違う動きとなってしまう。

#!/usr/bin/env bash
# procces置換のテスト

GVar="false"

mygrep() {
  GVar="true"
  grep "$1" "$2" 
}

cat test.txt | tr a-z A-Z | mygrep SOMEWORD -
echo $GVar

mygrep SOMEOWRD <(cat test.txt | tr a-z A-Z)
echo $GVar

上記スクリプトの実行結果は、以下のとおり。

..... SOMEWORD ......
false
..... SOMEWORD ......
true

ということで、これからはプロセス置換を積極的に利用していこうと考えた。

実は、プロセス置換には出力系の >(コマンド)もあるが、パイプやリダイレクトで代用できるケースが大半になるため、筆者には利用場面が思いつかなかった。(^^ゞ

また、何か気がついたら追記する。

関連ページ

Bashで無理やりエクセルファイル(xlsx)を編集する(邪道編)

(2024-05-09 初稿)

先日からBashを使って、CSVファイルを操作してエクセルファイル(xlsx)を作成する等の記事をアップした。

実際にやってみると、作成したエクセルファイルにほんの少しだけでも計算式や背景色、罫線等を追加したくなってきた。

この記事では、bashで無理やりエクセルファイルを編集する方法を記述する。

なお、調べた範囲ではBashで直接エクセルファイルを操作する方法は無いとのことなので、ここではbashのヒヤドキュメントを使ってpythonで操作するので、タイトルにあるとおりあくまでも邪道な方法である。

と言うことで、pythonで編集する方法の参考にしたサイトは以下の2つ。多謝。

この記事では、そもそも「pythonのファイルを作成する程までの編集はしない。」、「bashで他のコマンド等も利用していて、少しだけエクセルファイルを加工する。」等の場合のみ有効だと思われる。

それでは、早速スクリプトを示す。ちなみに、このスクリプトでは少しだけ汎用性を高めるために、pythonスクリプトbashの関数として実装してみた。

なお、ここでは既に「example.xlsx」というエクセルファイルがあるものと仮定しているので、無い場合は作成してから実行して欲しい。

#!/usr/bin/bash
# Modify Excel(xlsx) file

py-func() {
  # Arguments
  Excelfile=$1
  A1=$2

  # Pythonスクリプトを一時ファイルに書き出す
  cat << EOF > temp.py
import openpyxl
# 配置 背景色
from openpyxl.styles import Alignment, PatternFill
# 罫線
from openpyxl.styles.borders import Border, Side

# Excelファイルのパス
excel_file_path = "$Excelfile"

# Excelファイルを開く
wb = openpyxl.load_workbook(excel_file_path)

# シートを選択(デフォルトでは最初のシートを選択)
sheet = wb.active

# 例: A1セルに値を設定する
sheet['A1'] = "$A1"
# 配置
sheet['A1'].alignment = Alignment(horizontal='center', vertical='center')
# 背景色
sheet['A1'].fill = PatternFill(fgColor='ffff4d', bgColor='ffff4d', fill_type='solid')

sheet['B1'] = 1               # 数値
sheet['B2'] = 2
sheet['B3'] = '=SUM(B1:b2)'   # 計算式

# 線の種類 細実線 黒色
side = Side(style='thin', color='000000')
# 外枠線
border = Border(top=side, bottom=side, left=side, right=side)

sheet['D1'] = "文字列"        # 文字列
sheet['D2'] = 5
sheet['D3'] = 6

sheet['D1'].border = border   # 外枠線
sheet['D2'].border = border
sheet['D3'].border = border

# Excelファイルを保存
wb.save(excel_file_path)
EOF

  # Pythonスクリプトを実行
  python3 temp.py

  # 一時ファイルを削除
  rm temp.py
}

py-func "example.xlsx" "test text"

上記スクリプトに実行権を与えて、実行すると以下のとおりのエクセルファイルができあがる。

できあがったエクセルファイル

多分、このスクリプトが他の方の役に立つことは無いと思うが、エクセルファイルの編集の参考になれば幸いである。

 

関連ページ

Bashで楽天証券からダウンロードした保有商品一覧ファイル(CSV)を加工してエクセルファイル(xlsx)にする

(2024-05-08 初稿 )

新NISAが始まって、株を始めた方も多いのではと思う。

筆者も、最近、株をボチボチやっているのだが、最近、株価や為替相場が乱高下して日々の株価が気になっている。

そこで、少しでも楽ができるようにBashを用いて、楽天証券からダウンロードした保有商品一覧ファイル(CSV)から筆者が必要と思うデータを抽出し、エクセルファイル(xlsx)に変換するスクリプトを作ったので記事にする。

なお、CSVファイルの修正、加工方法及びCSVファイルからエクセルファイルへの変換方法については、以下の記事を参照願う。

楽天証券から保有商品一覧ファイル(CSV)のダウンロード

楽天証券のログイン後画面

赤丸の「保有商品一覧」をクリック。

保有商品一覧ファイル(CSV)のダウンロード

赤丸の「CSVで保存」をクリックすると、例えば「assetbalance(all)_20240508_075058.csv」等というファイル名のCSVファイルがダウンロードできる。

ダウンロードしたCSVファイルから必要なデータを抽出、加工

ダウンロードしたCSVファイルのファイル名の変更、必要なデータの抽出、口座名の変更などを行い、自分の使いやすいエクセルファイルに加工する。

ファイル名の加工

上述のとおりダウンロードしたファイル名は「assetbalance(all)_20240508_075058.csv」のようになるので、ファイル名は「rs-20240508_075058.csv」とする。筆者の好みで決めた名前なので、好きに変更願う。

なお、最終的なエクセルファイルは、このページのスクリプトだと「20240508_075058.xlsx」になる。

filename="assetbalance(all)_20240508_075058.csv"
csvfilename=rs-${filename#*_}

bashの文字列置換は便利だね。

必要なデータ

必要なデータは人により異なると思うが、一例として筆者は以下のとおりとした。

"銘柄","口座","保有数量","[単位]","平均取得価格","[単位]","現在値","[単位]","時価評価額[円]","評価損益[円]","評価損益[%]"

各自お好きなように変更を。

口座名の簡略化

新しいNISAが始まって、名称も古い「つみたてNISA」、新しい「NISAつみたて投資枠」、「NISA成長投資枠」とやや長い名前が多かったので、短い名前に変更している。

具体的には、「つみたてNISA ⇒ 積立」、「NISAつみたて投資枠 ⇒ 新積立」、「NISA成長投資枠 ⇒ 成長」としているが、この辺もお好みで変更して欲しい。

なお、「特定」はそのまま「特定」で使っている。

  IFS='"' read -a vary <<< "$1"
  #echo "${vary[@]}"
  case ${vary[7]} in
    "つみたてNISA")
        class="積立";;
    "NISAつみたて投資枠")
        class="新積立";;
    "NISA成長投資枠")
        class="成長";;
    *)
        class=${vary[7]}
  esac

CSVファイルをエクセルファイル(xlsx)に

上記リンクにも記述したが、以下のとおりLibreOfficeを用いてCSVファイルからエクセルファイル(xlsx)を作成する。

# 44 カンマ区切り 34 ダブルクォート
# 文字コード 76: UTF-8 60: Windows-932 64: Shift-JIS 72:ISO-2022-JP 
$ /usr/bin/libreoffice --headless --convert-to xlsx --infilter=xlsx:44,34,76 "$csvfilename"

スクリプトの全体と使い方

上記の処理を含んだスクリプト全体としては、以下のとおりである。

なお、スクリプトの名前は「r-stocks」としたが、お好きなように。

#!/usr/bin/env bash
# rakuten stocks list
# 楽天証券からDownloadしたcsvファイルを加工、表示
# 2024-04-24 ver0.01 start
# 2024-04-29 ver0.03 csv filename and add xlsx file

Usage="r-stocks rakuten downloaded stocks list csv file modify and display program
  [Usage] r-stocks target-csv
"
CTitle='"銘柄","口座","保有数量","[単位]","平均取得価格","[単位]","現在値","[単位]","時価評価額[円]","評価損益[円]","評価損益[%]"'

put_value() {
  IFS='"' read -a vary <<< "$1"
  #echo "${vary[@]}"

  case ${vary[7]} in
    "つみたてNISA")
        class="積立";;
    "NISAつみたて投資枠")
        class="新積立";;
    "NISA成長投資枠")
        class="成長";;
    *)
        class=${vary[7]}
  esac

  echo \""${vary[5]}"\",\""$class"\",\""${vary[9]}"\",\""${vary[11]}"\",\
    \""${vary[13]}"\",\""${vary[15]}"\",\""${vary[17]}"\",\""${vary[19]}"\",\
    \""${vary[29]}"\",\""${vary[33]}"\",\""${vary[35]}"\"
}

if  $# != 1 ; then
  echo "$Usage"
  exit
fi

csvfilename=rs-${1#*_}
#echo $csvfilename

# (必要があれば)文字コードUTF-8に変換
conv_file=$(/usr/bin/iconv -f SHIFT_JIS -t UTF-8 "$1")

prn_flag=0

echo $CTitle > "$csvfilename"

while read line; do
   $line =~ "種別"  && prn_flag=1
   $prn_flag == 1 && ($line =~ ^\"米国株式\"  || $line =~ ^\"投資信託\")  && put_value "$line" >> "$csvfilename"
done <<< "${conv_file}" 

# options from https://qiita.com/shota243/items/0ef67d786785bcf5b60f
# 44 カンマ区切り 34 ダブルクォート
# 文字コード 76: UTF-8 60: Windows-932 64: Shift-JIS 72:ISO-2022-JP 
# https://qiita.com/j0306043/items/fcc9546056eeca5b025a
# Warning: failed to launch javaldx - java may not function correctly
# apt install default-jre libreoffice-java-common
/usr/bin/libreoffice --headless --convert-to xlsx --infilter=xlsx:44,34,76 "$csvfilename"

上記のスクリプトに実行権を与えて、実行する場合は以下のとおり。

$ chmod +x r-stocks  # 初回のみ
$ r-stocks ~/Downloads/assetbalance(all)_20240508_075058.csv

実行結果は、カレントディレクトリに「20240508_075058.xlsx」が作成されるので、このファイルを開くと以下のとおり。

ほとんど、筆者の趣味のスクリプトだが、どなたかの参考になれば幸い。

関連ページ

Bashのパイプを利用した関数呼び出しの罠

(2024-05-01 初稿)

よく言われていることだが、Bashでパイプを使うと、サブシェルを使うと思わぬ弊害がでる記事はよく見ていたのだが、自分でスクリプトを作成してハマってみて、ようやく理解できた。

確認のサンプルスクリプト

関数の呼び出しの引数をつなげて、グローバル変数に保存し、エコー出力しながら、最後に変数全体を出力するスクリプト

#!/usr/bin/env bash
# sample script global variable with pipe redirect

G_Var=""

ex_func() {
  G_Var+=" $1"
  echo "$G_Var"
}

ex_func "Big"                    # ここを変更
ex_func "Dog"                    # ここを変更
echo "Last: "${G_Var}

上記スクリプトを実行すると、期待どおり、以下になる。

 Big
 Big Dog
Last:  Big Dog

しかし、上記スクリプトの「ここを変更」の部分を以下のようにパイプを使うように変更すると、以下のとおりおかしな結果になる。

ex_func "Big" | tee test.txt
ex_func "Dog" | tee -a test.txt
 Big
 Dog
Last: 

パイプを利用することで、呼び出した関数がサブシェルで実行されるため、呼び出し元の変数は変更されないのが理由らしい。

ちなみに、「ここを変更」の部分を、以下のとおりリダイレクトを利用すると、正常に動作する。

ex_func "Big" > test.txt
ex_func "Dog" >> test.txt
Last:  Big Dog

もともと動作していたスクリプトをついでにファイルにも保存しようとしてteeコマンドで関数を呼び出したのが原因。

これからスクリプトを作成するときには気をつけないとね。

 

LibreOfficeを使ってコマンドラインでCSVファイルをエクセルファイル(xlsx)ファイルに変換する

(2024-04-30 初稿 -2024-05-01 追記)

先日からCSVファイルを操作するスクリプトを作成している。

作成する中で、LibreOfficeコマンドラインCSVファイルをエクセルファイル(xlsx)に変換する機能があることを見つけた。

最初は、CSVファイルを右クリックして、LibreOfficeまたはExcelで読み込めば、ダイアログが出て普通に読み込めるから不要かな…と思ったのだが、以下の2つの理由から変換のスクリプトを作成することにした。

  1. CSVファイルが多数ある場合等に変換を自動化したい
  2. LibreOfficeの変換のオプションが多数あり、覚えられない

ワンライナーBashスクリプトなので、さっそく作成した。

ちなみに、筆者はDebian 12(bookworm)の環境で、以下のとおり。

#!/usr/bin/env bash
# convert csv-file to xlsx file
# ver0.01 [2024-04-30] start

/usr/bin/libreoffice --headless --convert-to xlsx --infilter=xlsx:44,34,76 "$1"

特にわかりにくいのは、--infilterのオプションで、上記の2番めのリンクに詳細が記載されているが、ここでも主な物をメモとして残す。

44:  カンマ区切り

34:  ダブルクォート

76: 文字コード UTF-8

      その他文字コード  60: Windows-932  64: Shift-JIS 72: ISO-2022-JP

例えば、上記スクリプトをcsv2xlsxと命名し、実行権を与え。以下のように実行する。

$ chmod +x csv2xlsx
$ csv2xlsx csv-file

(2024-05-01追記)

書き忘れたが、上記コマンド実行して、以下のワーニングが出るときには、パッケージを追加でインストール。

Warning: failed to launch javaldx - java may not function correctly

$ apt install default-jre libreoffice-java-common

(追記終了)

ディレクトリにあるcsvファイルを一括して変換する場合は、以下のとおり。

for f in *.csv; do csv2xlsx "$f"; done

以上、どなたかの参考になれば幸い。

関連ページ

Bashでカンマ区切りのCSVファイルを扱う

(2024-04-26 初稿)

こちらのblogは、ちょっと久しぶりにアップする。

最近、株の乱高下が激しいので、楽天証券保有株一覧を見ているのだけど、不要な列があったり、ちょっと特殊な集計をしたかったりするので、自分で表計算ソフトにちまちまとコピぺしていたんだけど、いい加減アホらしくなったので、python等で書けばちゃんと表計算ソフトのファイルを作成することができるが、テキストファイルが好きなのでBashの勉強のためにスクリプトを作ってみた。

ありがたいことに、楽天証券からは保有株一覧のファイルをダウンロードできるので、カンマ区切りのCSVファイルをダウンロードして利用することにした。

楽天証券CSVだけならば、変な文字列も無いのですぐにできたのだが、もう少し汎用的なCSVファイルでも、動作するようにしてみた。

まずは、カンマ区切りのCSVだからとIFSのデリミタをカンマ(,)してset関数で分割を考えたが、数字の1000単位のカンマがあり、あえなく撃沈。試行錯誤の結果、結局はダブルクォートを目印(デリミタ)にして、データを区切ることにした。

入力行から複数の値を取得するのは、read関数を使うと便利。

簡単なサンプルスクリプト

#!/usr/bin/env bash
# csv-split
# csvファイルの値を配列に
# 2024-04-25 ver0.01 start

test_line='"あ,い! う","a! b,c","123,456,789", "4,321"'

IFS='"' read  v1 v2 v3 v4 v5 v6 v7 v8 <<< "$test_line"
echo 'v1=' \""$v1"\"         #⇒ v1= ""
echo 'v2=' \""$v2"\"         # ⇒ v2= "あ,い! う"
echo 'v3=' \""$v3"\"         # ⇒ v3= ","
echo 'v4=' \""$v4"\"         # ⇒ v4= "a! b,c"
echo 'v6=' \""$v6"\"         # ⇒ v6=  "123,456,789"
echo 'v8=' \""$v8"\"         # ⇒ v8=  "4,321"
echo 'need_value=' \""$v4"\",\""$v8"\"  # ⇒ need_value= "a! b,c","4,321"

ダブルクォートをデリミタにしたことにより、最初の変数(v1)に空白、次(v2)に値、その次(v3)がカンマ、と偶数番目の変数に値が読み込まれる。

また、任意の値を選択して取得することも可能。

固定化したCSVファイルなら良いが、もう少し汎用性をもたせて読み込む値(変数)の数が変わる場合は、以下のとおりreadに-aオプションを付けて配列として読み込む方が都合が良い。

IFS='"' read -a csv_ary <<< "$test_line"
echo 'csv_ary[0]=' \""${csv_ary[0]}"\"  # ⇒ csv_ary[0]= ""
echo 'csv_ary[1]=' \""${csv_ary[1]}"\"  # ⇒ csv_ary[1]= "あ,い! う"
echo 'csv_ary[2]=' \""${csv_ary[2]}"\"  # ⇒ csv_ary[2]= ","
echo 'csv_ary[3]=' \""${csv_ary[3]}"\"  # ⇒ csv_ary[3]= "a! b,c"
(以下、省略)

配列の添字が、0から始まっているので、今度は奇数番目に値が入っている。

1番目⇒1、2番目⇒3、3番目⇒5の添字を指定するが、n番目のデータは2n-1の添字を使えば値を取得できる。

また、値の順番を変更できるようにorderを指定できるようにし、かつ、関数にしたものが以下のとおり。

#!/usr/bin/env bash
# csv-split
# csvファイルを配列に分割する
# 2024-04-25 ver0.01 start
test_line='"あ,い! う","a! b,c","123,456,789", "4,321"'

get_csv_value() {
  # csvの値を指定する順番で出力
  local rslt=""
  IFS='"' read -a csv_ary <<< "$1"
  #echo 'csv_ary=' "${csv_ary[@]}"
  IFS=, read -a order_ary <<< $2
  #echo 'order_ary=' "${order_ary[@]}"
  for ((i=0; i<${#order_ary[@]}; i++)); do
    j=$((${order_ary[$i]} * 2 -1))      # n番目は配列の2n-1番目
    rslt+=\""${csv_ary[$j]}"\",
  done
  echo ${rslt%,}     # 最後の,の削除

order="2,1,3"         # 順番の指定
putline=$(get_csv_value "$test_line" "$order")
echo $putline

実行権を与えてから、実行すると以下のとおり。

# csv-split
"a! b,c","あ,い! う","123,456,789"

今回、read関数で配列にすることが便利なことがわかった。

どなたかの参考になれば幸い。

関連ページ

Debian 12(Bookworm)で、Bluetooth USBアダプタ(UB500)を接続してワイヤレスヘッドホンをつなぐ

(2024-04-03 初稿)

過去に何度もBluetooth接続で、スピーカーやマウスをつないだけど、接続方法をすぐに忘れてしまうのでメモを残す。

今回は、デスクトップのDebianに有線接続でヘッドホンをつないでいたんだけど、少しケーブルが短かったため、ヘッドホンを付けたまま自由な姿勢がとれるようにBluetooth接続のワイヤレスヘッドホンをつなぐことを目的とした。

まずは、筆者の環境を確認。

$ cat /etc/debian_version 
12.5
$ uname -a
Linux hoge 6.1.0-18-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.76-1 (2024-02-01) x86_64 GNU/Linux

今回は、以下のサイトを参考にさせていただいた。多謝。m(__)m

デスクトップPCにはBluetoothアダプタが付いていなかったので、以下のUB500というBluetooth USBアダプタを購入した。

上記USB500をデスクトップPCに挿し込んでから、lsusbで確認。

$ lsusb
(前略)
Bus 001 Device 003: ID 2357:0604 TP-Link TP-Link UB500 Adapter
(後略)

ちゃんと認識しているよう。

今回接続するのは、骨伝導のワイヤレスヘッドホンでというもの。

以下のリンクよりも古い型なので、少し形状が異なるけど…

参考にしたサイトにあるとおり、Bluetooth関連のパッケージをインストールして、起動時から使えるように。

$ sudo apt update
$ sudo apt install bluetooth bluez bluez-tools rfkill
$ sudo systemctl start bluetooth
$ sudo systemctl enable bluetooth

以下のコマンドで、Bluetoothのstatusを確認。

$ sudo systemctl status bluetoothbluetooth.service - Bluetooth service<
     Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; preset: en>
     Active: active (running) since Sat 2024-03-30 15:10:32 JST; 1min 14s ago
       Docs: man:bluetoothd(8)
   Main PID: 685 (bluetoothd)
     Status: "Running"
      Tasks: 1 (limit: 19037)
     Memory: 3.3M
        CPU: 28ms
     CGroup: /system.slice/bluetooth.service
             └─685 /usr/libexec/bluetooth/bluetoothdr

rfkillのリストに入っていないことを確認。

$ rfkill list

bluetoothctlコマンドで、scanしてペアリングする。

$ bluetoothctl
[bluetooth]# scan on [NEW] Device EB:06:EF:66:A9:E1 X 11

X11のヘッドホンが見つかれば、スキャンは成功。

つづけて、bluetoothctlコマンドの中で、ペアリング。

# pair EB:06:EF:66:A9:E1
Attempting to pair with EB:06:EF:66:A9:E1

たぶんペアリングは問題なく終了すると思われる。

問題は、次のコネクト。筆者の場合は、bluetoothを再起動したりして、何度かチャレンジする中で、以下のとおり接続に成功した。

# connect EB:06:EF:66:A9:E1
Attempting to connect to EB:06:EF:66:A9:E1
[CHG] Device EB:06:EF:66:A9:E1 Connected: yes
[NEW] Endpoint /org/bluez/hci0/dev_EB_06_EF_66_A9_E1/sep8 
[NEW] Endpoint /org/bluez/hci0/dev_EB_06_EF_66_A9_E1/sep6 
[NEW] Endpoint /org/bluez/hci0/dev_EB_06_EF_66_A9_E1/sep5 
[NEW] Endpoint /org/bluez/hci0/dev_EB_06_EF_66_A9_E1/sep3 
[NEW] Endpoint /org/bluez/hci0/dev_EB_06_EF_66_A9_E1/sep1 
[NEW] Transport /org/bluez/hci0/dev_EB_06_EF_66_A9_E1/sep5/fd0 
Connection successful
[CHG] Transport /org/bluez/hci0/dev_EB_06_EF_66_A9_E1/sep5/fd0 State: active
[CHG] Transport /org/bluez/hci0/dev_EB_06_EF_66_A9_E1/sep5/fd0 Volume: 0x0050 (80)
[CHG] Device EB:06:EF:66:A9:E1 ServicesResolved: yes
[CHG] Transport /org/bluez/hci0/dev_EB_06_EF_66_A9_E1/sep5/fd0 State: idle

接続に成功したら、exitコマンドでbluetoothctlコマンドを抜ける。

# exit

毎回、Bluetoothctlコマンドを叩くのは大変なので、以下のスクリプトを利用すると良い。

$ cat bin/blule-connect
#/usr/bin/env bash
# bluetooth connect
bluetoothctl << EOC
connect EB:06:EF:66:A9:E1
quit
EOC

それでもコマンドを叩くのはちょっとという方は、以下のGUIをインストールすると良い。

筆者の場合、LXDEを使っているので、以下のとおり。

$sudo apt-get install blueman

gnome-bluetooth (for GNOME)

$ sudo apt install gnome-bluetooth

bluedevil (for KDE)

$ apt install bluedevil

bluemanをインストールした状態は、以下のとおり。

BluemanでX11の状態を確認

以上、他の方の参考になれば幸い。

関連ページ