Browse Source

check mw callable without questions, fix readme

pull/276/head
Roland Puntaier 5 years ago
parent
commit
7915e30725
5 changed files with 228 additions and 161 deletions
  1. +1
    -1
      .gitignore
  2. +38
    -15
      README.rst
  3. +123
    -116
      bin/mw
  4. +62
    -25
      mw.1
  5. +4
    -4
      test/test_mw.bats

+ 1
- 1
.gitignore View File

@@ -3,4 +3,4 @@ personal.muttrc
*.gpg
*.pyc
accounts/
*mailsynclastrun
*mw.lastrun

+ 38
- 15
README.rst View File

@@ -37,6 +37,19 @@ DESCRIPTION
**mw** configures **mbsync**, **getmail**, **msmtp** and **mutt** in one go.
**mutt** stands for **mutt** or **neomutt**.

**mw** asks the user for the information it needs.
They cannot be provided as parameters to the command.
It is still possible to script **mw** by defining variables.
See the commands section.

*mutt-wizard.muttrc* is linked in your *muttrc*.
Have this line there, if you prefer your own settings::

# source /usr/share/mutt-wizard/mutt-wizard.muttrc

You will need to keep the binding of *i,g,C,M* to *noop*, though,
because of the generated bindings in the account muttrc.

COMMANDS
========

@@ -48,6 +61,7 @@ If the parameter contains @ an email is assumed and synced.
Add new email

First you decide, whether you want to configure

- **mbsync**, **getmail**, **msmtp** to sync emails independently from **mutt** using **mw**,
- or just **mutt**.
For an IMAP server **mutt** becomes very slow.
@@ -59,6 +73,12 @@ If the parameter contains @ an email is assumed and synced.
If you are lucky, your email server is there.
Else **mw** will prompt you.

Add an email without questions, e.g.::

a=x.y@gmail.com mwtype=offline mwaddr=$a mwlogin=$a mwpass=mutt-wizard-$a mwserverinfo="gmail.com,imap.gmail.com,993,smtp.gmail.com,587" mwname="your name" mw add

*mwserverinfo* can be omitted, if the email domain is in the accompanied *domains.csv*.

*ls|list*

List all email accounts configured by mutt-wizard
@@ -67,6 +87,10 @@ If the parameter contains @ an email is assumed and synced.

Remove the configuration files for an already configured email

Remove without questions the email whose generated muttrc starts with 1::

mwpick=1 mw rm <<<y

*purge*

Removes all mw generated mutt settings and
@@ -78,10 +102,19 @@ If the parameter contains @ an email is assumed and synced.

Files are under *.config* or *$XDG_CONFIG_HOME*

If you don't want questions::

mw purge <<<y

*cron*

Toggle a cronjob that periodically syncs mail

Without questions::

mwcronremove=yes mw cron
mwcronminutes=99 mw cron

*sync*

Syncs mail for all email accounts managed by **mw** (whose paths end in the email).
@@ -89,21 +122,11 @@ If the parameter contains @ an email is assumed and synced.
This is the default, if no parameter is given.
If an email address is given, only that email is synced.

- Every **mw** sync run will re-generate the **mutt** configuration
from the configuration files for **mbsync**, **getmail** and **msmtp**.
So you could edit them after or not use *mw add* at all.

Just keep the *Path*, *path* and *account* ending in the email address.

- The generated **mutt** configuration has these bindings

- */usr/share/mutt-wizard/mutt-wizard.muttrc* is linked in your *muttrc*.
Have this line there, if you prefer your own settings::

# source /usr/share/mutt-wizard/mutt-wizard.muttrc
Every **mw** sync run will re-generate the **mutt** configuration
from the configuration files for **mbsync**, **getmail** and **msmtp**.
So you could edit them after or not use *mw add* at all.

You will need to keep the binding of *i,g,C,M* to *noop*, though,
because of the generated bindings in the account muttrc.
Just keep the *Path*, *path* and *account* ending in the email address.

DEPENDENCIES
============
@@ -155,7 +178,7 @@ MUTT CONFIGURATION

Once everything is setup, you’ll use **mutt** to access your mail.

The accompanied */usr/share/mutt-wizard.muttrc* modifies some **mutt** defaults.
The accompanied *mutt-wizard.muttrc* modifies some **mutt** defaults.
Look there for a complete list.

Here an overview:


+ 123
- 116
bin/mw View File

@@ -19,7 +19,7 @@ mwmuttrc="$mwmuttdir/muttrc"
# Directory for account settings
mwaccmuttdir="$mwmuttdir/accounts"
# Generated at every full sync
mwgenmuttaccs=$mwmuttdir/mw_generated.muttrc
mwgenmuttaccs=$mwmuttdir/mw_gen_mutt_accounts.muttrc
# Location of mail storage
mwmaildir="${MAILDIR:-$HOME/mail}"
# Regex to confirm valid email address
@@ -45,25 +45,54 @@ _mwaddrs() {
mwaddrs="$(find "$mwaccmuttdir" -type f | grep -o "[1-9]-.*.muttrc" | sed "s/-/: /;s/\.muttrc//" | sort -n)"
}

_mwlist() {
_mwaddrs && [ -n "$mwaddrs" ] && echo "${mwaddrs//.mwonofftype./ }"
_mwgetpass() {
while : ; do pass rm -f "$mwpass" >/dev/null 2>&1
pass insert "$mwpass" && break; done ;
}

_mwadd() {
type gpg >/dev/null 2>&1 && GPG="gpg" || GPG="gpg2"
[ -z "$PASSWORD_STORE_DIR" ] && PASSWORD_STORE_DIR="$HOME/.password-store"
[ -r "$PASSWORD_STORE_DIR/.gpg-id" ] &&
"$GPG" --list-secret-keys $(cat "$PASSWORD_STORE_DIR/.gpg-id") >/dev/null 2>&1 || {
printf "\`pass\` must be installed and initialized to encrypt passwords.\\nBe sure it is installed and run \`pass init <yourgpgemail>\`.\\n"
printf "If you don't have a GPG public private key pair, run \`$GPG --full-gen-key\` first.\\n"
return 1
}
_mwcheckcert && _mwcheckinternet && _mwasktype && _mwaskinfo && _mwprofiles && _mwtryconnect && _mwfinalize || _mwdelete
_mwcheckcert() {
for mwcrt in "/etc/ssl/certs/ca-certificates.crt" "/etc/pki/tls/certs/ca-bundle.crt" "/etc/ssl/ca-bundle.pem" \
"/etc/pki/tls/cacert.pem" "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem" "/etc/ssl/cert.pem" "/usr/local/share/ca-certificates/"
do
[ -f "$mwcrt" ] && mwsslcert="$mwcrt" && break
done || { echo "CA Certificate not found. Please install one or link it to /etc/ssl/certs/ca-certificates.crt" && return 1 ;}
}

_mwgetpass() {
while : ; do pass rm -f "$mwpass" >/dev/null 2>&1
pass insert "$mwpass" && break; done ;
_mwcheckinternet() {
# Checks for internet connection
if type systemctl >/dev/null; then
if ! systemctl --type service | grep net | grep active > /dev/null; then
echo "No internet connection."
return 1
fi
else
if ! ping -q -c 1 1.1.1.1 > /dev/null; then
echo "No internet connection (ping failed)."
return 1
fi
fi
}

_mwasktype() {
if [ -z "$mwtype" ]; then
while : ; do
printf "Do you want to sync your mails using the command 'mw' outside mutt? [yes/no]\\n"
printf "'no' makes Neomutt slow for IMAP accounts, so probably you want 'yes'.\\n\t"
read -r mwoffline
case "$mwoffline" in
[Yy][Ee][Ss]) mwtype="offline" && break ;;
[Nn][Oo]) mwtype="online" && break ;;
*) echo "Write out either yes or no completely. Try again or press ctrl-c to quit." ;;
esac
done
fi
if [ "$mwtype" == "offline" ]; then
! type "$prefix/bin/msmtp" >/dev/null && printf "\033[31m\`msmtp\` must be installed. You can do that afterwards.\\n\033[0m"
else
! ( type mutt >/dev/null || type neomutt >/dev/null ) && printf "\033[31m\`mutt\` must be installed. You can do that afterwards.\\n\033[0m"
fi

return 0
}

_mwaskinfo() {
@@ -78,8 +107,10 @@ _mwaskinfo() {
done
fi
mwdomain="$(echo "$mwaddr" | sed "s/.*@//")"
printf "\\nSearching for \033[32m%s\033[0m in \033[34m\`domains.csv\`\033[0m..." "$mwdomain"
mwserverinfo="$(grep "^$mwdomain" "$mwshare/domains.csv" 2>/dev/null)"
if [ -z "$mwserverinfo" ]; then
printf "\\nSearching for \033[32m%s\033[0m in \033[34m\`domains.csv\`\033[0m..." "$mwdomain"
mwserverinfo="$(grep "^$mwdomain" "$mwshare/domains.csv" 2>/dev/null)"
fi
if [ -z "$mwserverinfo" ]; then
printf "Your email domain is not known to $_MW_.\\nType in your settings.\\n"
printf "Usually you find them by an internet search.\\n"
@@ -273,6 +304,28 @@ _mwtryconnect() {
fi
}

_mwnotmuchauto() {
[ -z "$NOTMUCH_CONFIG" ] && NOTMUCH_CONFIG="$HOME/.notmuch-config"
[ -f "$NOTMUCH_CONFIG" ] && return 0
mkdir -p "${NOTMUCH_CONFIG%/*}"
cat > "$NOTMUCH_CONFIG" <<EOF
[database]
path=$mwmaildir
[user]
name=$mwname
primary_email=$mwaddr
[new]
tags=new
ignore=
[search]
exclude_tags=deleted;spam;
[maildir]
synchronize_flags=true
[crypto]
gpg_path=$GPG"
EOF
}

_mwfinalize() { # new mwaccmuttrc
if [ "$mwtype" = "online" ]; then
if [ ! "${mwkind::3}" = "pop" ]; then
@@ -292,12 +345,45 @@ _mwfinalize() { # new mwaccmuttrc
return 0
}

_mwdelete() {
[ "$mwaccmaildirWasThere" = "NO" ] && rm -rf "$mwaccmaildir" &>/dev/null
rm -f "$mwaccmuttrc" &>/dev/null
if [ "$mwtype" = "offline" ]; then # not online
sed -i "/${mwaccmuttrc//\//\\\/}/d" "$mwgenmuttaccs" &>/dev/null
sed -i "/account $mwaddr/,/^\(\s*$\|account\)/d" "$mwmsmtprc" &>/dev/null
if [ -f "$mwgetmaildir/$mwaddr" ]; then
rm -f "$mwgetmaildir/$mwaddr" &>/dev/null
else
sed -i "/IMAPStore $mwaddr-remote$/,/# End $_MW_ profile/d" "$mwmbsyncrc" &>/dev/null
fi
else
sed -i "/${mwaccmuttrc//\//\\\/}/d" "$mwmuttrc" &>/dev/null
rm -rf "$mwacccachedir" &>/dev/null
fi
}

_mwadd() {
type gpg >/dev/null 2>&1 && GPG="gpg" || GPG="gpg2"
[ -z "$PASSWORD_STORE_DIR" ] && PASSWORD_STORE_DIR="$HOME/.password-store"
[ -r "$PASSWORD_STORE_DIR/.gpg-id" ] &&
"$GPG" --list-secret-keys $(cat "$PASSWORD_STORE_DIR/.gpg-id") >/dev/null 2>&1 || {
printf "\`pass\` must be installed and initialized to encrypt passwords.\\nBe sure it is installed and run \`pass init <yourgpgemail>\`.\\n"
printf "If you don't have a GPG public private key pair, run \`$GPG --full-gen-key\` first.\\n"
return 1
}
_mwcheckcert && _mwcheckinternet && _mwasktype && _mwaskinfo && _mwprofiles && _mwtryconnect && _mwfinalize || _mwdelete
}

_mwconfirm() {
printf "[y/N]: Do you want to %s?\\n\t" "$@" && read -r mwinput && ! echo "$mwinput" | grep -i "^y$\|^yes$" >/dev/null \
&& printf "That doesn't seem like a yes to me.\\n\\n" && return 1
return 0 ;
}

_mwlist() {
_mwaddrs && [ -n "$mwaddrs" ] && echo "${mwaddrs//.mwonofftype./ }"
}

_mwpick() {
printf "Select an accounts to %s:\\n" "$1"
_mwlist
@@ -311,68 +397,34 @@ _mwpick() {
return 0 ;
}

_mwdelete() {
[ "$mwaccmaildirWasThere" = "NO" ] && rm -rf "$mwaccmaildir" &>/dev/null
rm -f "$mwaccmuttrc" &>/dev/null
if [ "$mwtype" = "offline" ]; then # not online
sed -i "/${mwaccmuttrc//\//\\\/}/d" "$mwgenmuttaccs" &>/dev/null
sed -i "/account $mwaddr/,/^\(\s*$\|account\)/d" "$mwmsmtprc" &>/dev/null
if [ -f "$mwgetmaildir/$mwaddr" ]; then
rm -f "$mwgetmaildir/$mwaddr" &>/dev/null
else
sed -i "/IMAPStore $mwaddr-remote$/,/# End $_MW_ profile/d" "$mwmbsyncrc" &>/dev/null
fi
else
sed -i "/${mwaccmuttrc//\//\\\/}/d" "$mwmuttrc" &>/dev/null
rm -rf "$mwacccachedir" &>/dev/null
fi
}

_mwcron() {
! pgrep cron >/dev/null && echo "No cron manager running. Install/enable one and then select this option again." && return 1
if crontab -l | grep "mw sync" >/dev/null; then
echo "Active mail sync cronjob detected. Do you want to remove it?"
printf "\033[36m\t"
[ -z "$mwcronremove" ] && read -r mwcronremove
printf "\033[0m"
if [ -z $mwcronminutes ]; then
echo "Active mail sync cronjob detected. Do you want to remove it?"
printf "\033[36m\t"
[ -z $mwcronremove ] && read -r mwcronremove
printf "\033[0m"
else # remove to add again
mwcronremove="yes"
fi
echo "$mwcronremove" | grep -i "^y\(es\)*$" >/dev/null && crontab -l | sed '/mw sync/d' | crontab - >/dev/null \
&& echo "Mail sync turned off."
else
&& echo "mw cronjob removed."
[ -z $mwcronminutes ] && return
fi
if [ -z $mwcronminutes ]; then
echo "How many minutes between each mail sync?"
printf "\033[36m\t"
[ -z $mwcronminutes ] && read -r mwcronminutes
printf "\033[0m"
while ! echo "$mwcronminutes" | grep "^[1-9]\+$" >/dev/null; do
printf "That doesn't look like a number. How many minutes between each mail sync?\\n\033[36m\t"
read -r mwcronminutes
printf "\033[0m"
done
(crontab -l; echo "*/$mwcronminutes * * * * export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus; export DISPLAY=:0; $(type mw | cut -d' ' -f3) sync") \
| crontab - && \
echo "Cronjob added. Mail will sync every $mwcronminutes minutes. Be sure you have your cron manager running."
fi
}

_mwasktype() {
if [ -z "$mwtype" ]; then
while : ; do
printf "Do you want to sync your mails using the command 'mw' outside mutt? [yes/no]\\n"
printf "'no' makes Neomutt slow for IMAP accounts, so probably you want 'yes'.\\n\t"
read -r mwoffline
case "$mwoffline" in
[Yy][Ee][Ss]) mwtype="offline" && break ;;
[Nn][Oo]) mwtype="online" && break ;;
*) echo "Write out either yes or no completely. Try again or press ctrl-c to quit." ;;
esac
done
fi
if [ "$mwtype" == "offline" ]; then
! type "$prefix/bin/msmtp" >/dev/null && printf "\033[31m\`msmtp\` must be installed. You can do that afterwards.\\n\033[0m"
else
! ( type mutt >/dev/null || type neomutt >/dev/null ) && printf "\033[31m\`mutt\` must be installed. You can do that afterwards.\\n\033[0m"
fi

return 0
while ! echo "$mwcronminutes" | grep "^[1-9]\+$" >/dev/null; do
printf "That doesn't look like a number. How many minutes between each mail sync?\\n\033[36m\t"
read -r mwcronminutes
printf "\033[0m"
done
(crontab -l; echo "*/$mwcronminutes * * * * export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus; export DISPLAY=:0; $(type mw | cut -d' ' -f3) sync") \
| crontab - && echo "mw cronjob added. Mail will sync every $mwcronminutes minutes. Be sure you have your cron manager running."
}

_mwpurge() {
@@ -392,28 +444,6 @@ _mwpurge() {
echo "All configs and account settings have been purged."
}

_mwnotmuchauto() {
[ -z "$NOTMUCH_CONFIG" ] && NOTMUCH_CONFIG="$HOME/.notmuch-config"
[ -f "$NOTMUCH_CONFIG" ] && return 0
mkdir -p "${NOTMUCH_CONFIG%/*}"
cat > "$NOTMUCH_CONFIG" <<EOF
[database]
path=$mwmaildir
[user]
name=$mwname
primary_email=$mwaddr
[new]
tags=unread;inbox;
ignore=
[search]
exclude_tags=deleted;spam;
[maildir]
synchronize_flags=true
[crypto]
gpg_path=$GPG"
EOF
}

# run after mbsync to create mutt settings for $mwaddr
_mwgenmwaccmuttrc() {
mwaccmaildir="$mwmaildir/$mwaddr"
@@ -638,29 +668,6 @@ _mwmuttemails() {
done
}

_mwcheckcert() {
for mwcrt in "/etc/ssl/certs/ca-certificates.crt" "/etc/pki/tls/certs/ca-bundle.crt" "/etc/ssl/ca-bundle.pem" \
"/etc/pki/tls/cacert.pem" "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem" "/etc/ssl/cert.pem" "/usr/local/share/ca-certificates/"
do
[ -f "$mwcrt" ] && mwsslcert="$mwcrt" && break
done || { echo "CA Certificate not found. Please install one or link it to /etc/ssl/certs/ca-certificates.crt" && return 1 ;}
}

_mwcheckinternet() {
# Checks for internet connection
if type systemctl >/dev/null; then
if ! systemctl --type service | grep net | grep active > /dev/null; then
echo "No internet connection."
return 1
fi
else
if ! ping -q -c 1 1.1.1.1 > /dev/null; then
echo "No internet connection (ping failed)."
return 1
fi
fi
}

_mwsync() {
unset mwemails
mwtype="offline"


+ 62
- 25
mw.1 View File

@@ -50,6 +50,24 @@ Sync email without mutt.
\f[B]mw\f[R] configures \f[B]mbsync\f[R], \f[B]getmail\f[R],
\f[B]msmtp\f[R] and \f[B]mutt\f[R] in one go.
\f[B]mutt\f[R] stands for \f[B]mutt\f[R] or \f[B]neomutt\f[R].
.PP
\f[B]mw\f[R] asks the user for the information it needs.
They cannot be provided as parameters to the command.
It is still possible to script \f[B]mw\f[R] by defining variables.
See the commands section.
.PP
\f[I]mutt-wizard.muttrc\f[R] is linked in your \f[I]muttrc\f[R].
Have this line there, if you prefer your own settings:
.IP
.nf
\f[C]
# source /usr/share/mutt-wizard/mutt-wizard.muttrc
\f[R]
.fi
.PP
You will need to keep the binding of \f[I]i,g,C,M\f[R] to
\f[I]noop\f[R], though, because of the generated bindings in the account
muttrc.
.SH COMMANDS
.PP
Without command parameter \f[B]sync\f[R] is assumed.
@@ -60,9 +78,12 @@ If the parameter contains \[at] an email is assumed and synced.
.PP
Add new email
.PP
First you decide, whether you want to configure - \f[B]mbsync\f[R],
\f[B]getmail\f[R], \f[B]msmtp\f[R] to sync emails independently from
\f[B]mutt\f[R] using \f[B]mw\f[R], - or just \f[B]mutt\f[R].
First you decide, whether you want to configure
.IP \[bu] 2
\f[B]mbsync\f[R], \f[B]getmail\f[R], \f[B]msmtp\f[R] to sync emails
independently from \f[B]mutt\f[R] using \f[B]mw\f[R],
.IP \[bu] 2
or just \f[B]mutt\f[R].
For an IMAP server \f[B]mutt\f[R] becomes very slow.
So normally you enter \f[B]yes\f[R] here.
.PP
@@ -72,6 +93,17 @@ So normally you enter \f[B]yes\f[R] here.
ports.
If you are lucky, your email server is there.
Else \f[B]mw\f[R] will prompt you.
.PP
Add an email without questions, e.g.:
.IP
.nf
\f[C]
a=x.y\[at]gmail.com mwtype=offline mwaddr=$a mwlogin=$a mwpass=mutt-wizard-$a mwserverinfo=\[dq]gmail.com,imap.gmail.com,993,smtp.gmail.com,587\[dq] mwname=\[dq]your name\[dq] mw add
\f[R]
.fi
.PP
\f[I]mwserverinfo\f[R] can be omitted, if the email domain is in the
accompanied \f[I]domains.csv\f[R].
.RE
.PP
\f[I]ls|list\f[R]
@@ -84,6 +116,14 @@ List all email accounts configured by mutt-wizard
.RS
.PP
Remove the configuration files for an already configured email
.PP
Remove without questions the email whose generated muttrc starts with 1:
.IP
.nf
\f[C]
mwpick=1 mw rm <<<y
\f[R]
.fi
.RE
.PP
\f[I]purge\f[R]
@@ -106,12 +146,29 @@ Removes all mw generated mutt settings and
\f[I].config/msmtp/config\f[R]
.PP
Files are under \f[I].config\f[R] or \f[I]$XDG_CONFIG_HOME\f[R]
.PP
If you don\[aq]t want questions:
.IP
.nf
\f[C]
mw purge <<<y
\f[R]
.fi
.RE
.PP
\f[I]cron\f[R]
.RS
.PP
Toggle a cronjob that periodically syncs mail
.PP
Without questions:
.IP
.nf
\f[C]
mwcronremove=yes mw cron
mwcronminutes=99 mw cron
\f[R]
.fi
.RE
.PP
\f[I]sync\f[R]
@@ -122,35 +179,15 @@ end in the email).
.PP
This is the default, if no parameter is given.
If an email address is given, only that email is synced.
.IP \[bu] 2
.PP
Every \f[B]mw\f[R] sync run will re-generate the \f[B]mutt\f[R]
configuration from the configuration files for \f[B]mbsync\f[R],
\f[B]getmail\f[R] and \f[B]msmtp\f[R].
So you could edit them after or not use \f[I]mw add\f[R] at all.
.RS 2
.PP
Just keep the \f[I]Path\f[R], \f[I]path\f[R] and \f[I]account\f[R]
ending in the email address.
.RE
.IP \[bu] 2
The generated \f[B]mutt\f[R] configuration has these bindings
.IP \[bu] 2
\f[I]/usr/share/mutt-wizard/mutt-wizard.muttrc\f[R] is linked in your
\f[I]muttrc\f[R].
Have this line there, if you prefer your own settings:
.RS 2
.IP
.nf
\f[C]
# source /usr/share/mutt-wizard/mutt-wizard.muttrc
\f[R]
.fi
.PP
You will need to keep the binding of \f[I]i,g,C,M\f[R] to
\f[I]noop\f[R], though, because of the generated bindings in the account
muttrc.
.RE
.RE
.SH DEPENDENCIES
.PP
Required for email setup or operation:
@@ -209,7 +246,7 @@ sudo make install
Once everything is setup, you\[cq]ll use \f[B]mutt\f[R] to access your
mail.
.PP
The accompanied \f[I]/usr/share/mutt-wizard.muttrc\f[R] modifies some
The accompanied \f[I]mutt-wizard.muttrc\f[R] modifies some
\f[B]mutt\f[R] defaults.
Look there for a complete list.
.PP


+ 4
- 4
test/test_mw.bats View File

@@ -15,7 +15,7 @@ run_only_test() {
# these are called for every test
setup()
{
# run_only_test 2
#run_only_test 6
rm -rf mwtesttmp
XDG_CONFIG_HOME=mwtesttmp/config \
MAILDIR=mwtesttmp/share/mail \
@@ -112,13 +112,13 @@ teardown()
# 6
@test "cron" {
mwcronminutes=99 run _mwcron
chkline="${lines[2]}"
[ "${chkline::14}" = "Cronjob added." ]
chkline="${lines[1]}"
[ "${chkline::16}" = "mw cronjob added" ]
function crontab() { echo 'mw sync'; }
export crontab
mwcronremove=y run _mwcron
chkline="${lines[1]}"
[ "${chkline#*turned}" = " off." ]
[ "${chkline#*cronjob}" = " removed." ]
}

# 7


Loading…
Cancel
Save