My motd script works using run-parts but no output when I log in via ssh











up vote
0
down vote

favorite












This is my 00-motd (-rwxr-xr-x) file:



#!/usr/bin/env python3

DISK_A = '/dev/sda2'
DISK_B = '/dev/sdb1'

import locale
locale.setlocale(locale.LC_TIME, 'pl_PL.UTF-8')

# https://github.com/maxogden/cool-ascii-faces
cool = [
u"( .-. )",
u"( .o.)",
u"( `·´ )",
u"( ° ͜ ʖ °)",
u"( ͡° ͜ʖ ͡°)",
u"( ⚆ _ ⚆ )",
u"( ︶︿︶)",
u"( ゚ヮ゚)",
u"(\/)(°,,,°)(\/)",
u"(¬_¬)",
u"(¬º-°)¬",
u"(¬‿¬)",
u"(°ロ°)☝",
u"(´・ω・)っ",
u"(ó ì_í)",
u"(ʘᗩʘ')",
u"(ʘ‿ʘ)",
u"(̿▀̿ ̿Ĺ̯̿̿▀̿ ̿)̄",
u"(͡° ͜ʖ ͡°)",
u"ᕦ( ͡° ͜ʖ ͡°)ᕤ",
u"(ಠ_ಠ)",
u"(ಠ‿ಠ)",
u"(ಠ⌣ಠ)",
u"(ಥ_ಥ)",
u"(ಥ﹏ಥ)",
u"(ง ͠° ͟ل͜ ͡°)ง",
u"(ง ͡ʘ ͜ʖ ͡ʘ)ง",
u"(ง •̀_•́)ง",
u"(ง'̀-'́)ง",
u"(ง°ل͜°)ง",
u"(ง⌐□ل͜□)ง",
u"(ღ˘⌣˘ღ)",
u"(ᵔᴥᵔ)",
u"(•ω•)",
u"(•◡•)/",
u"(⊙ω⊙)",
u"(⌐■_■)",
u"(─‿‿─)",
u"(╯°□°)╯",
u"(◕‿◕)",
u"(☞゚∀゚)☞",
u"(❍ᴥ❍ʋ)",
u"(っ◕‿◕)っ",
u"(づ。◕‿‿◕。)づ",
u"(ノಠ益ಠ)ノ",
u"(ノ・∀・)ノ",
u"(;一_一)",
u"(`◔ ω ◔´)",
u"(。◕‿‿◕。)",
u"(ノ◕ヮ◕)ノ",
u"*<{:¬{D}}}",
u"=^.^=",
u"t(-.-t)",
u"| (• ◡•)|",
u"~(˘▾˘~)",
u"¬_¬",
u"¯(°_o)/¯",
u"¯\_(ツ)_/¯",
u"°Д°",
u"ɳ༼ຈل͜ຈ༽ɲ",
u"ʅʕ•ᴥ•ʔʃ",
u"ʕ´•ᴥ•`ʔ",
u"ʕ•ᴥ•ʔ",
u"ʕ◉.◉ʔ",
u"ʕㅇ호ㅇʔ",
u"ʕ;•`ᴥ•´ʔ",
u"ʘ‿ʘ",
u"͡° ͜ʖ ͡°",
u"ζ༼Ɵ͆ل͜Ɵ͆༽ᶘ",
u"Ѱζ༼ᴼل͜ᴼ༽ᶘѰ",
u"ب_ب",
u"٩◔̯◔۶",
u"ಠ_ಠ",
u"ಠoಠ",
u"ಠ~ಠ",
u"ಠ‿ಠ",
u"ಠ⌣ಠ",
u"ಠ╭╮ಠ",
u"ರ_ರ",
u"ง ͠° ل͜ °)ง",
u"๏̯͡๏﴿",
u"༼ ºººººل͟ººººº ༽",
u"༼ ºل͟º ༽",
u"༼ ºل͟º༼",
u"༼ ºل͟º༽",
u"༼ ͡■ل͜ ͡■༽",
u"༼ つ ◕_◕ ༽つ",
u"༼ʘ̚ل͜ʘ̚༽",
u"ლ(´ڡ`ლ)",
u"ლ(́◉◞౪◟◉‵ლ)",
u"ლ(ಠ益ಠლ)",
u"ᄽὁȍ ̪őὀᄿ",
u"ᔑ•ﺪ͟͠•ᔐ",
u"ᕕ( ᐛ )ᕗ",
u"ᕙ(⇀‸↼‶)ᕗ",
u"ᕙ༼ຈل͜ຈ༽ᕗ",
u"ᶘ ᵒᴥᵒᶅ",
u"(ノಥ益ಥ)ノ",
u"≧☉_☉≦",
u"⊙▃⊙",
u"⊙﹏⊙",
u"┌( ಠ_ಠ)┘",
u"╚(ಠ_ಠ)=┐",
u"◉_◉",
u"◔ ⌣ ◔",
u"◔̯◔",
u"◕‿↼",
u"◕‿◕",
u"☉_☉",
u"☜(⌒▽⌒)☞",
u"☼.☼",
u"♥‿♥",
u"⚆ _ ⚆",
u"✌(-‿-)✌",
u"〆(・∀・@)",
u"ノ( º _ ºノ)",
u"ノ( ゜-゜ノ)",
u"ヽ( ͝° ͜ʖ͡°)ノ",
u"ヽ(`Д´)ノ",
u"ヽ༼° ͟ل͜ ͡°༽ノ",
u"ヽ༼ʘ̚ل͜ʘ̚༽ノ",
u"ヽ༼ຈل͜ຈ༽ง",
u"ヽ༼ຈل͜ຈ༽ノ",
u"ヽ༼Ὸل͜ຈ༽ノ",
u"ヾ(⌐■_■)ノ",
u"꒰・◡・๑꒱",
u"﴾͡๏̯͡๏﴿",
u"。◕‿◕。",
u"ʕノ◔ϖ◔ʔノ",
u"(ノಠ益ಠ)ノ彡┻━┻",
u"(╯°□°)╯︵ ┻━┻",
u"꒰•̥̥̥̥̥̥̥ ﹏ •̥̥̥̥̥̥̥̥๑꒱",
u"ಠ_ರೃ",
u"(ू˃̣̣̣̣̣̣︿˂̣̣̣̣̣̣ ू)",
u"(ꈨຶꎁꈨຶ)۶”",
u"(ꐦ°᷄д°᷅)",
u"(۶ૈ ۜ ᵒ̌▱๋ᵒ̌ )۶ૈ=͟͟͞͞ ⌨",
u"₍˄·͈༝·͈˄₎◞ ̑̑ෆ⃛",
u"(*゚⚙͠ ∀ ⚙͠)ノ❣",
u"٩꒰・ัε・ั ꒱۶",
u"ヘ(。□°)ヘ",
u"˓˓(ृ  ु ॑꒳’)ु(ृ’꒳ ॑ ृ )ु˒˒˒",
u"꒰✘Д✘◍꒱",
u"૮( ᵒ̌ૢཪᵒ̌ૢ )ა",
u"“ψ(`∇´)ψ",
u"ಠﭛಠ",
u"(๑>ᴗ<๑)",
u"(۶ꈨຶꎁꈨຶ )۶ʸᵉᵃʰᵎ",
u"٩(•̤̀ᵕ•̤́๑)ᵒᵏᵎᵎᵎᵎ",
u"(oT-T)尸",
u"(✌゚∀゚)☞",
u"ಥ‿ಥ",
u"ॱ॰⋆(˶ॢ‾᷄﹃‾᷅˵ॢ)",
u"┬┴┬┴┤ (ಠ├┬┴┬┴",
u"( ˘ ³˘)♥",
u"Σ (੭ु ຶਊ ຶ)੭ु⁾⁾",
u"(⑅ ॣ•͈ᴗ•͈ ॣ)",
u"ヾ(´¬`)ノ",
u"(•̀o•́)ง",
u"(๑•॒̀ ູ॒•́๑)",
u"⚈้̤͡ ˌ̫̮ ⚈้̤͡",
u"=͟͟͞͞ =͟͟͞͞ ヘ( ´Д`)ノ",
u"(((╹д╹;)))",
u"•̀.̫•́✧",
u"(ᵒ̤̑ ₀̑ ᵒ̤̑)",
u"\_(ʘ_ʘ)_/",
u"乙(ツ)乙",
u"乙(のっの)乙",
u"ヾ(¯∇ ̄๑)",
u"\_(ʘ_ʘ)_/",
u"༼;´༎ຶ ۝ ༎ຶ༽",
u"(▀̿Ĺ̯▀̿ ̿)",
u"(ノ◕ヮ◕)ノ*:・゚✧",
u"(ノ◕ヮ◕)ノ*:・゚✧ ✧゚・: *ヽ(◕ヮ◕ヽ)",
u"┬┴┬┴┤ ͜ʖ ͡°) ├┬┴┬┴",
u"┬┴┬┴┤(・_├┬┴┬┴",
u"(͡ ͡° ͜ つ ͡͡°)",
u"( ͡°╭͜ʖ╮͡° )",
u"(• ε •)",
u"[̲̅$̲̅(̲̅ ͡° ͜ʖ ͡°̲̅)̲̅$̲̅]",
u"| (• ◡•)| (❍ᴥ❍ʋ)",
u"(◕‿◕✿)",
u"(╯°□°)╯︵ ʞooqǝɔɐɟ",
u"(☞゚ヮ゚)☞ ☜(゚ヮ゚☜)",
u"(づ ̄ ³ ̄)づ",
u"(;´༎ຶД༎ຶ`)",
u"♪~ ᕕ(ᐛ)ᕗ",
u"༼ つ ͡° ͜ʖ ͡° ༽つ",
u"༼ つ ಥ_ಥ ༽つ",
u"ಥ_ಥ",
u"( ͡ᵔ ͜ʖ ͡ᵔ )",
u"ヾ(⌐■_■)ノ♪",
u"~(˘▾˘~)",
u"\ (•◡•) /",
u"(~˘▾˘)~",
u"(._.) ( l: ) ( .-. ) ( :l ) (._.)",
u"༼ ºل͟º ༼ ºل͟º ༼ ºل͟º ༽ ºل͟º ༽ ºل͟º ༽",
u"┻━┻ ︵ヽ(`Д´)ノ︵ ┻━┻",
u"ᕦ(ò_óˇ)ᕤ",
u"(•_•) ( •_•)>⌐■-■ (⌐■_■)",
u"(☞ຈل͜ຈ)☞",
u"˙ ͜ʟ˙",
u"☜(˚▽˚)☞",
u"(。◕‿◕。)",
u"(╯°□°)╯︵( .o.)",
u"(っ˘ڡ˘ς)",
u"┬──┬ ノ( ゜-゜ノ)",
u"ಠ⌣ಠ",
u"( ಠ ͜ʖರೃ)",
u"ƪ(˘⌣˘)ʃ",
u"¯\(°_o)/¯",
u"ლ,ᔑ•ﺪ͟͠•ᔐ.ლ",
u"(´・ω・`)",
u"(´・ω・)っ由",
u"(° ͡ ͜ ͡ʖ ͡ °)",
u"Ƹ̵̡Ӝ̵̨̄Ʒ",
u"ಠ_ಥ",
u"ಠ‿↼",
u"(>ლ)",
u"(▰˘◡˘▰)",
u"(✿´‿`)",
u"◔ ⌣ ◔",
u"。゜(`Д´)゜。",
u"┬─┬ノ( º _ ºノ)",
u"(ó ì_í)=óò=(ì_í ò)",
u"(/) (°,,°) (/)",
u"┬─┬ ︵ /(.□. )",
u"^̮^",
u"(>人<)",
u"(~_^)",
u"(・.◤)",
u">_>",
u"(^̮^)",
u"=U",
u"(。╹ω╹。)",
u"ლ(╹◡╹ლ)",
u"(●´⌓`●)",
u"([∂]ω[∂])",
u"U^エ^U",
u"(〒ó〒)",
u"(T^T)",
u"(íoì)",
u"(#•v•#)",
u"(•^u^•)",
u"!(^3^)!",
u"\(°°\”)",
u"(°o°:)",
u"(° o°)!",
u"(oロo)!!",
u"(òロó)",
u"(ò皿ó)",
u"( ̄・_______・ ̄)",
u"ヾ(๑╹◡╹)ノ'",
u"(ლ╹◡╹)ლ",
u"(◞‸◟)",
u"(✿◖◡◗)",
u"( ´・‿・`)",
u"(*`益´*)がう",
u"(ヾノ'д'o)ナィナィ",
u"❤(◕‿◕✿)",
u"(◡‿◡*)❤",
u"(o'ω'o)",
u"(。・ˇ_ˇ・。)ムゥ…",
u"♬♩♫♪☻(●´∀`●)☺♪♫♩♬",
u"(✿ฺ◕ฺ‿◕ฺ)ウフッ♥",
u"(つД⊂)エーン",
u"(つД・)チラ",
u"(*´ω`*)",
u"(✪‿✪)ノ",
u"╲(。◕‿◕。)╱",
u"ლ(^o^ლ)"
]

import random
r = random.SystemRandom()
cool_choice = r.choice(cool)

import time as t
time = t.strftime('%H:%M')
date = t.strftime('%A %d %B %Y').title()

import multiprocessing
cores = multiprocessing.cpu_count()

uptime = 0
idletime = 0
load = ''

with open('/proc/uptime', 'r') as f:
s = f.readline().split()
uptime = float(s[0])
idletime = float(s[1])

with open('/proc/loadavg', 'r') as f:
s = f.readline().split()
load = (s[0] + ', ' + s[1] + ', ' + s[2]).rjust(28, ' ')
processes = (s[3]).rjust(23, ' ')

import pendulum
uptime_for_humans = pendulum.duration(minutes=uptime // 60).in_words()
idle_percentage = '%.2f' % round(idletime / cores / uptime * 100, 2)

uptime_gui = uptime_for_humans + (idle_percentage + ' % idling').rjust(72 - len(uptime_for_humans), ' ')

import psutil
memory = psutil.virtual_memory()
partitions = psutil.disk_partitions()

disk_a_dev = '/'
disk_a = psutil.disk_usage('/')
disk_b_dev = '/'
disk_b = psutil.disk_usage('/')

for partition in partitions:
if DISK_A == partition.device:
disk_a_dev = partition.device
disk_a = psutil.disk_usage(partition.mountpoint)
if DISK_B == partition.device:
disk_b_dev = partition.device
disk_b = psutil.disk_usage(partition.mountpoint)

def bytes_for_humans(b, ndigits=2):
units = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'] # Powodzenia kurwa
depth = 0
value = b

while (value // 1024):
depth += 1
value /= 1024

if depth:
value = ('%.2f' % round(value, ndigits))

return str(value) + ' ' + units[depth]

disk_a_data = [
('%.2f' % round(disk_a.used / disk_a.total * 100, 2)).rjust(32 - len(disk_a_dev), ' '),
bytes_for_humans(disk_a.total).rjust(27, ' '),
bytes_for_humans(disk_a.free).rjust(27, ' '),
bytes_for_humans(disk_a.used).rjust(27, ' ')
]

disk_b_data = [
('%.2f' % round(disk_b.used / disk_b.total * 100, 2)).rjust(32 - len(disk_b_dev), ' '),
bytes_for_humans(disk_b.total).rjust(27, ' '),
bytes_for_humans(disk_b.free).rjust(27, ' '),
bytes_for_humans(disk_b.used).rjust(27, ' ')
]

mem_data = [
('%.2f' % round(memory.used / memory.total * 100, 2)).rjust(20, ' '),
bytes_for_humans(memory.total).rjust(23, ' '),
bytes_for_humans(memory.available).rjust(23, ' '),
bytes_for_humans(memory.free).rjust(23, ' '),
bytes_for_humans(memory.used).rjust(23, ' ')
]

print(f'''
┌─┐┬ ┬┌┐ ┌─┐┬─┐┌─┐┌─┐┬ ┬┬┬
└─┐│ │├┴┐├─┤├┬┘├─┤└─┐├─┤││ {time}
└─┘└─┘└─┘┴ ┴┴└─┴ ┴└─┘┴ ┴┴┴ {date}

{cool_choice}


┌ Uptime ──────────────────────────────────────────────────────────────────┐
│ {uptime_gui } │
└──────────────────────────────────────────────────────────────────────────┘
┌ System ────────────────────────────┐┌ Partitions ────────────────────────┐
│ Load: {load } ││ {disk_a_dev + disk_a_data[0] } % │
│ Processes: {processes } ││ Total: {disk_a_data[1] } │
└────────────────────────────────────┘│ Free: {disk_a_data[2] } │
┌ Memory ────────────────────────────┐│ Used: {disk_a_data[3] } │
│ Percentage: {mem_data[0] } % │├────────────────────────────────────┤
│ Total: {mem_data[1] } ││ {disk_b_dev + disk_b_data[0] } % │
│ Available: {mem_data[2] } ││ Total: {disk_b_data[1] } │
│ Free: {mem_data[3] } ││ Free: {disk_b_data[2] } │
│ Used: {mem_data[4] } ││ Used: {disk_b_data[3] } │
└────────────────────────────────────┘└────────────────────────────────────┘
''')


This is output of run-parts /etc/update-motd.d:



run-parts output



This is /etc/pam.d/login:



#
# The PAM configuration file for the Shadow `login' service
#

# Enforce a minimal delay in case of failure (in microseconds).
# (Replaces the `FAIL_DELAY' setting from login.defs)
# Note that other modules may require another minimal delay. (for example,
# to disable any delay, you should add the nodelay option to pam_unix)
auth optional pam_faildelay.so delay=3000000

# Outputs an issue file prior to each login prompt (Replaces the
# ISSUE_FILE option from login.defs). Uncomment for use
# auth required pam_issue.so issue=/etc/issue

# Disallows root logins except on tty's listed in /etc/securetty
# (Replaces the `CONSOLE' setting from login.defs)
#
# With the default control of this module:
# [success=ok new_authtok_reqd=ok ignore=ignore user_unknown=bad default=die]
# root will not be prompted for a password on insecure lines.
# if an invalid username is entered, a password is prompted (but login
# will eventually be rejected)
#
# You can change it to a "requisite" module if you think root may mis-type
# her login and should not be prompted for a password in that case. But
# this will leave the system as vulnerable to user enumeration attacks.
#
# You can change it to a "required" module if you think it permits to
# guess valid user names of your system (invalid user names are considered
# as possibly being root on insecure lines), but root passwords may be
# communicated over insecure lines.
auth [success=ok new_authtok_reqd=ok ignore=ignore user_unknown=bad default=die] pam_securetty.so

# Disallows other than root logins when /etc/nologin exists
# (Replaces the `NOLOGINS_FILE' option from login.defs)
auth requisite pam_nologin.so

# SELinux needs to be the first session rule. This ensures that any
# lingering context has been cleared. Without this it is possible
# that a module could execute code in the wrong domain.
# When the module is present, "required" would be sufficient (When SELinux
# is disabled, this returns success.)
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close

# Sets the loginuid process attribute
session required pam_loginuid.so

# SELinux needs to intervene at login time to ensure that the process
# starts in the proper default security context. Only sessions which are
# intended to run in the user's context should be run after this.
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open
# When the module is present, "required" would be sufficient (When SELinux
# is disabled, this returns success.)

# This module parses environment configuration file(s)
# and also allows you to use an extended config
# file /etc/security/pam_env.conf.
#
# parsing /etc/environment needs "readenv=1"
session required pam_env.so readenv=1
# locale variables are also kept into /etc/default/locale in etch
# reading this file *in addition to /etc/environment* does not hurt
session required pam_env.so readenv=1 envfile=/etc/default/locale

# Standard Un*x authentication.
@include common-auth

# This allows certain extra groups to be granted to a user
# based on things like time of day, tty, service, and user.
# Please edit /etc/security/group.conf to fit your needs
# (Replaces the `CONSOLE_GROUPS' option in login.defs)
auth optional pam_group.so

# Uncomment and edit /etc/security/time.conf if you need to set
# time restraint on logins.
# (Replaces the `PORTTIME_CHECKS_ENAB' option from login.defs
# as well as /etc/porttime)
# account requisite pam_time.so

# Uncomment and edit /etc/security/access.conf if you need to
# set access limits.
# (Replaces /etc/login.access file)
# account required pam_access.so

# Sets up user limits according to /etc/security/limits.conf
# (Replaces the use of /etc/limits in old login)
session required pam_limits.so

# Prints the last login info upon successful login
# (Replaces the `LASTLOG_ENAB' option from login.defs)
session optional pam_lastlog.so

# Prints the message of the day upon successful login.
# (Replaces the `MOTD_FILE' option in login.defs)
# This includes a dynamically generated part from /run/motd.dynamic
# and a static (admin-editable) part from /etc/motd.
session optional pam_motd.so motd=/run/motd.dynamic
session optional pam_motd.so noupdate

# Prints the status of the user's mailbox upon successful login
# (Replaces the `MAIL_CHECK_ENAB' option from login.defs).
#
# This also defines the MAIL environment variable
# However, userdel also needs MAIL_DIR and MAIL_FILE variables
# in /etc/login.defs to make sure that removing a user
# also removes the user's mail spool file.
# See comments in /etc/login.defs
session optional pam_mail.so standard

# Create a new session keyring.
session optional pam_keyinit.so force revoke

# Standard Un*x account and session
@include common-account
@include common-session
@include common-password


If I replace my script with something like this:



#!/usr/bin/env python3
print('test')


motd works but when I try to use my cool motd I don't get any output.
Any idea why this happens? Where I can find some logs or something to find out why there is no output? I'm using Ubuntu 18.10 Server



Solved



/etc/update-motd.d/00:



#!/bin/zsh

export LANG='en_US.UTF-8'
/usr/bin/env python3 /etc/update-motd.d/00.py









share|improve this question
























  • did you have a look at the last post here? linuxquestions.org/questions/debian-26/…
    – db429
    Nov 26 at 21:21










  • hi did you also edit your /etc/pam.d/sshd to hold the line session optional pam_motd.so motd=/run/motd.dynamic ?
    – db429
    Nov 26 at 21:28










  • '/etc/pam.d/sshd ' pastebin.com/Sfmin3dL
    – I hate linux so much
    Nov 27 at 18:07















up vote
0
down vote

favorite












This is my 00-motd (-rwxr-xr-x) file:



#!/usr/bin/env python3

DISK_A = '/dev/sda2'
DISK_B = '/dev/sdb1'

import locale
locale.setlocale(locale.LC_TIME, 'pl_PL.UTF-8')

# https://github.com/maxogden/cool-ascii-faces
cool = [
u"( .-. )",
u"( .o.)",
u"( `·´ )",
u"( ° ͜ ʖ °)",
u"( ͡° ͜ʖ ͡°)",
u"( ⚆ _ ⚆ )",
u"( ︶︿︶)",
u"( ゚ヮ゚)",
u"(\/)(°,,,°)(\/)",
u"(¬_¬)",
u"(¬º-°)¬",
u"(¬‿¬)",
u"(°ロ°)☝",
u"(´・ω・)っ",
u"(ó ì_í)",
u"(ʘᗩʘ')",
u"(ʘ‿ʘ)",
u"(̿▀̿ ̿Ĺ̯̿̿▀̿ ̿)̄",
u"(͡° ͜ʖ ͡°)",
u"ᕦ( ͡° ͜ʖ ͡°)ᕤ",
u"(ಠ_ಠ)",
u"(ಠ‿ಠ)",
u"(ಠ⌣ಠ)",
u"(ಥ_ಥ)",
u"(ಥ﹏ಥ)",
u"(ง ͠° ͟ل͜ ͡°)ง",
u"(ง ͡ʘ ͜ʖ ͡ʘ)ง",
u"(ง •̀_•́)ง",
u"(ง'̀-'́)ง",
u"(ง°ل͜°)ง",
u"(ง⌐□ل͜□)ง",
u"(ღ˘⌣˘ღ)",
u"(ᵔᴥᵔ)",
u"(•ω•)",
u"(•◡•)/",
u"(⊙ω⊙)",
u"(⌐■_■)",
u"(─‿‿─)",
u"(╯°□°)╯",
u"(◕‿◕)",
u"(☞゚∀゚)☞",
u"(❍ᴥ❍ʋ)",
u"(っ◕‿◕)っ",
u"(づ。◕‿‿◕。)づ",
u"(ノಠ益ಠ)ノ",
u"(ノ・∀・)ノ",
u"(;一_一)",
u"(`◔ ω ◔´)",
u"(。◕‿‿◕。)",
u"(ノ◕ヮ◕)ノ",
u"*<{:¬{D}}}",
u"=^.^=",
u"t(-.-t)",
u"| (• ◡•)|",
u"~(˘▾˘~)",
u"¬_¬",
u"¯(°_o)/¯",
u"¯\_(ツ)_/¯",
u"°Д°",
u"ɳ༼ຈل͜ຈ༽ɲ",
u"ʅʕ•ᴥ•ʔʃ",
u"ʕ´•ᴥ•`ʔ",
u"ʕ•ᴥ•ʔ",
u"ʕ◉.◉ʔ",
u"ʕㅇ호ㅇʔ",
u"ʕ;•`ᴥ•´ʔ",
u"ʘ‿ʘ",
u"͡° ͜ʖ ͡°",
u"ζ༼Ɵ͆ل͜Ɵ͆༽ᶘ",
u"Ѱζ༼ᴼل͜ᴼ༽ᶘѰ",
u"ب_ب",
u"٩◔̯◔۶",
u"ಠ_ಠ",
u"ಠoಠ",
u"ಠ~ಠ",
u"ಠ‿ಠ",
u"ಠ⌣ಠ",
u"ಠ╭╮ಠ",
u"ರ_ರ",
u"ง ͠° ل͜ °)ง",
u"๏̯͡๏﴿",
u"༼ ºººººل͟ººººº ༽",
u"༼ ºل͟º ༽",
u"༼ ºل͟º༼",
u"༼ ºل͟º༽",
u"༼ ͡■ل͜ ͡■༽",
u"༼ つ ◕_◕ ༽つ",
u"༼ʘ̚ل͜ʘ̚༽",
u"ლ(´ڡ`ლ)",
u"ლ(́◉◞౪◟◉‵ლ)",
u"ლ(ಠ益ಠლ)",
u"ᄽὁȍ ̪őὀᄿ",
u"ᔑ•ﺪ͟͠•ᔐ",
u"ᕕ( ᐛ )ᕗ",
u"ᕙ(⇀‸↼‶)ᕗ",
u"ᕙ༼ຈل͜ຈ༽ᕗ",
u"ᶘ ᵒᴥᵒᶅ",
u"(ノಥ益ಥ)ノ",
u"≧☉_☉≦",
u"⊙▃⊙",
u"⊙﹏⊙",
u"┌( ಠ_ಠ)┘",
u"╚(ಠ_ಠ)=┐",
u"◉_◉",
u"◔ ⌣ ◔",
u"◔̯◔",
u"◕‿↼",
u"◕‿◕",
u"☉_☉",
u"☜(⌒▽⌒)☞",
u"☼.☼",
u"♥‿♥",
u"⚆ _ ⚆",
u"✌(-‿-)✌",
u"〆(・∀・@)",
u"ノ( º _ ºノ)",
u"ノ( ゜-゜ノ)",
u"ヽ( ͝° ͜ʖ͡°)ノ",
u"ヽ(`Д´)ノ",
u"ヽ༼° ͟ل͜ ͡°༽ノ",
u"ヽ༼ʘ̚ل͜ʘ̚༽ノ",
u"ヽ༼ຈل͜ຈ༽ง",
u"ヽ༼ຈل͜ຈ༽ノ",
u"ヽ༼Ὸل͜ຈ༽ノ",
u"ヾ(⌐■_■)ノ",
u"꒰・◡・๑꒱",
u"﴾͡๏̯͡๏﴿",
u"。◕‿◕。",
u"ʕノ◔ϖ◔ʔノ",
u"(ノಠ益ಠ)ノ彡┻━┻",
u"(╯°□°)╯︵ ┻━┻",
u"꒰•̥̥̥̥̥̥̥ ﹏ •̥̥̥̥̥̥̥̥๑꒱",
u"ಠ_ರೃ",
u"(ू˃̣̣̣̣̣̣︿˂̣̣̣̣̣̣ ू)",
u"(ꈨຶꎁꈨຶ)۶”",
u"(ꐦ°᷄д°᷅)",
u"(۶ૈ ۜ ᵒ̌▱๋ᵒ̌ )۶ૈ=͟͟͞͞ ⌨",
u"₍˄·͈༝·͈˄₎◞ ̑̑ෆ⃛",
u"(*゚⚙͠ ∀ ⚙͠)ノ❣",
u"٩꒰・ัε・ั ꒱۶",
u"ヘ(。□°)ヘ",
u"˓˓(ृ  ु ॑꒳’)ु(ृ’꒳ ॑ ृ )ु˒˒˒",
u"꒰✘Д✘◍꒱",
u"૮( ᵒ̌ૢཪᵒ̌ૢ )ა",
u"“ψ(`∇´)ψ",
u"ಠﭛಠ",
u"(๑>ᴗ<๑)",
u"(۶ꈨຶꎁꈨຶ )۶ʸᵉᵃʰᵎ",
u"٩(•̤̀ᵕ•̤́๑)ᵒᵏᵎᵎᵎᵎ",
u"(oT-T)尸",
u"(✌゚∀゚)☞",
u"ಥ‿ಥ",
u"ॱ॰⋆(˶ॢ‾᷄﹃‾᷅˵ॢ)",
u"┬┴┬┴┤ (ಠ├┬┴┬┴",
u"( ˘ ³˘)♥",
u"Σ (੭ु ຶਊ ຶ)੭ु⁾⁾",
u"(⑅ ॣ•͈ᴗ•͈ ॣ)",
u"ヾ(´¬`)ノ",
u"(•̀o•́)ง",
u"(๑•॒̀ ູ॒•́๑)",
u"⚈้̤͡ ˌ̫̮ ⚈้̤͡",
u"=͟͟͞͞ =͟͟͞͞ ヘ( ´Д`)ノ",
u"(((╹д╹;)))",
u"•̀.̫•́✧",
u"(ᵒ̤̑ ₀̑ ᵒ̤̑)",
u"\_(ʘ_ʘ)_/",
u"乙(ツ)乙",
u"乙(のっの)乙",
u"ヾ(¯∇ ̄๑)",
u"\_(ʘ_ʘ)_/",
u"༼;´༎ຶ ۝ ༎ຶ༽",
u"(▀̿Ĺ̯▀̿ ̿)",
u"(ノ◕ヮ◕)ノ*:・゚✧",
u"(ノ◕ヮ◕)ノ*:・゚✧ ✧゚・: *ヽ(◕ヮ◕ヽ)",
u"┬┴┬┴┤ ͜ʖ ͡°) ├┬┴┬┴",
u"┬┴┬┴┤(・_├┬┴┬┴",
u"(͡ ͡° ͜ つ ͡͡°)",
u"( ͡°╭͜ʖ╮͡° )",
u"(• ε •)",
u"[̲̅$̲̅(̲̅ ͡° ͜ʖ ͡°̲̅)̲̅$̲̅]",
u"| (• ◡•)| (❍ᴥ❍ʋ)",
u"(◕‿◕✿)",
u"(╯°□°)╯︵ ʞooqǝɔɐɟ",
u"(☞゚ヮ゚)☞ ☜(゚ヮ゚☜)",
u"(づ ̄ ³ ̄)づ",
u"(;´༎ຶД༎ຶ`)",
u"♪~ ᕕ(ᐛ)ᕗ",
u"༼ つ ͡° ͜ʖ ͡° ༽つ",
u"༼ つ ಥ_ಥ ༽つ",
u"ಥ_ಥ",
u"( ͡ᵔ ͜ʖ ͡ᵔ )",
u"ヾ(⌐■_■)ノ♪",
u"~(˘▾˘~)",
u"\ (•◡•) /",
u"(~˘▾˘)~",
u"(._.) ( l: ) ( .-. ) ( :l ) (._.)",
u"༼ ºل͟º ༼ ºل͟º ༼ ºل͟º ༽ ºل͟º ༽ ºل͟º ༽",
u"┻━┻ ︵ヽ(`Д´)ノ︵ ┻━┻",
u"ᕦ(ò_óˇ)ᕤ",
u"(•_•) ( •_•)>⌐■-■ (⌐■_■)",
u"(☞ຈل͜ຈ)☞",
u"˙ ͜ʟ˙",
u"☜(˚▽˚)☞",
u"(。◕‿◕。)",
u"(╯°□°)╯︵( .o.)",
u"(っ˘ڡ˘ς)",
u"┬──┬ ノ( ゜-゜ノ)",
u"ಠ⌣ಠ",
u"( ಠ ͜ʖರೃ)",
u"ƪ(˘⌣˘)ʃ",
u"¯\(°_o)/¯",
u"ლ,ᔑ•ﺪ͟͠•ᔐ.ლ",
u"(´・ω・`)",
u"(´・ω・)っ由",
u"(° ͡ ͜ ͡ʖ ͡ °)",
u"Ƹ̵̡Ӝ̵̨̄Ʒ",
u"ಠ_ಥ",
u"ಠ‿↼",
u"(>ლ)",
u"(▰˘◡˘▰)",
u"(✿´‿`)",
u"◔ ⌣ ◔",
u"。゜(`Д´)゜。",
u"┬─┬ノ( º _ ºノ)",
u"(ó ì_í)=óò=(ì_í ò)",
u"(/) (°,,°) (/)",
u"┬─┬ ︵ /(.□. )",
u"^̮^",
u"(>人<)",
u"(~_^)",
u"(・.◤)",
u">_>",
u"(^̮^)",
u"=U",
u"(。╹ω╹。)",
u"ლ(╹◡╹ლ)",
u"(●´⌓`●)",
u"([∂]ω[∂])",
u"U^エ^U",
u"(〒ó〒)",
u"(T^T)",
u"(íoì)",
u"(#•v•#)",
u"(•^u^•)",
u"!(^3^)!",
u"\(°°\”)",
u"(°o°:)",
u"(° o°)!",
u"(oロo)!!",
u"(òロó)",
u"(ò皿ó)",
u"( ̄・_______・ ̄)",
u"ヾ(๑╹◡╹)ノ'",
u"(ლ╹◡╹)ლ",
u"(◞‸◟)",
u"(✿◖◡◗)",
u"( ´・‿・`)",
u"(*`益´*)がう",
u"(ヾノ'д'o)ナィナィ",
u"❤(◕‿◕✿)",
u"(◡‿◡*)❤",
u"(o'ω'o)",
u"(。・ˇ_ˇ・。)ムゥ…",
u"♬♩♫♪☻(●´∀`●)☺♪♫♩♬",
u"(✿ฺ◕ฺ‿◕ฺ)ウフッ♥",
u"(つД⊂)エーン",
u"(つД・)チラ",
u"(*´ω`*)",
u"(✪‿✪)ノ",
u"╲(。◕‿◕。)╱",
u"ლ(^o^ლ)"
]

import random
r = random.SystemRandom()
cool_choice = r.choice(cool)

import time as t
time = t.strftime('%H:%M')
date = t.strftime('%A %d %B %Y').title()

import multiprocessing
cores = multiprocessing.cpu_count()

uptime = 0
idletime = 0
load = ''

with open('/proc/uptime', 'r') as f:
s = f.readline().split()
uptime = float(s[0])
idletime = float(s[1])

with open('/proc/loadavg', 'r') as f:
s = f.readline().split()
load = (s[0] + ', ' + s[1] + ', ' + s[2]).rjust(28, ' ')
processes = (s[3]).rjust(23, ' ')

import pendulum
uptime_for_humans = pendulum.duration(minutes=uptime // 60).in_words()
idle_percentage = '%.2f' % round(idletime / cores / uptime * 100, 2)

uptime_gui = uptime_for_humans + (idle_percentage + ' % idling').rjust(72 - len(uptime_for_humans), ' ')

import psutil
memory = psutil.virtual_memory()
partitions = psutil.disk_partitions()

disk_a_dev = '/'
disk_a = psutil.disk_usage('/')
disk_b_dev = '/'
disk_b = psutil.disk_usage('/')

for partition in partitions:
if DISK_A == partition.device:
disk_a_dev = partition.device
disk_a = psutil.disk_usage(partition.mountpoint)
if DISK_B == partition.device:
disk_b_dev = partition.device
disk_b = psutil.disk_usage(partition.mountpoint)

def bytes_for_humans(b, ndigits=2):
units = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'] # Powodzenia kurwa
depth = 0
value = b

while (value // 1024):
depth += 1
value /= 1024

if depth:
value = ('%.2f' % round(value, ndigits))

return str(value) + ' ' + units[depth]

disk_a_data = [
('%.2f' % round(disk_a.used / disk_a.total * 100, 2)).rjust(32 - len(disk_a_dev), ' '),
bytes_for_humans(disk_a.total).rjust(27, ' '),
bytes_for_humans(disk_a.free).rjust(27, ' '),
bytes_for_humans(disk_a.used).rjust(27, ' ')
]

disk_b_data = [
('%.2f' % round(disk_b.used / disk_b.total * 100, 2)).rjust(32 - len(disk_b_dev), ' '),
bytes_for_humans(disk_b.total).rjust(27, ' '),
bytes_for_humans(disk_b.free).rjust(27, ' '),
bytes_for_humans(disk_b.used).rjust(27, ' ')
]

mem_data = [
('%.2f' % round(memory.used / memory.total * 100, 2)).rjust(20, ' '),
bytes_for_humans(memory.total).rjust(23, ' '),
bytes_for_humans(memory.available).rjust(23, ' '),
bytes_for_humans(memory.free).rjust(23, ' '),
bytes_for_humans(memory.used).rjust(23, ' ')
]

print(f'''
┌─┐┬ ┬┌┐ ┌─┐┬─┐┌─┐┌─┐┬ ┬┬┬
└─┐│ │├┴┐├─┤├┬┘├─┤└─┐├─┤││ {time}
└─┘└─┘└─┘┴ ┴┴└─┴ ┴└─┘┴ ┴┴┴ {date}

{cool_choice}


┌ Uptime ──────────────────────────────────────────────────────────────────┐
│ {uptime_gui } │
└──────────────────────────────────────────────────────────────────────────┘
┌ System ────────────────────────────┐┌ Partitions ────────────────────────┐
│ Load: {load } ││ {disk_a_dev + disk_a_data[0] } % │
│ Processes: {processes } ││ Total: {disk_a_data[1] } │
└────────────────────────────────────┘│ Free: {disk_a_data[2] } │
┌ Memory ────────────────────────────┐│ Used: {disk_a_data[3] } │
│ Percentage: {mem_data[0] } % │├────────────────────────────────────┤
│ Total: {mem_data[1] } ││ {disk_b_dev + disk_b_data[0] } % │
│ Available: {mem_data[2] } ││ Total: {disk_b_data[1] } │
│ Free: {mem_data[3] } ││ Free: {disk_b_data[2] } │
│ Used: {mem_data[4] } ││ Used: {disk_b_data[3] } │
└────────────────────────────────────┘└────────────────────────────────────┘
''')


This is output of run-parts /etc/update-motd.d:



run-parts output



This is /etc/pam.d/login:



#
# The PAM configuration file for the Shadow `login' service
#

# Enforce a minimal delay in case of failure (in microseconds).
# (Replaces the `FAIL_DELAY' setting from login.defs)
# Note that other modules may require another minimal delay. (for example,
# to disable any delay, you should add the nodelay option to pam_unix)
auth optional pam_faildelay.so delay=3000000

# Outputs an issue file prior to each login prompt (Replaces the
# ISSUE_FILE option from login.defs). Uncomment for use
# auth required pam_issue.so issue=/etc/issue

# Disallows root logins except on tty's listed in /etc/securetty
# (Replaces the `CONSOLE' setting from login.defs)
#
# With the default control of this module:
# [success=ok new_authtok_reqd=ok ignore=ignore user_unknown=bad default=die]
# root will not be prompted for a password on insecure lines.
# if an invalid username is entered, a password is prompted (but login
# will eventually be rejected)
#
# You can change it to a "requisite" module if you think root may mis-type
# her login and should not be prompted for a password in that case. But
# this will leave the system as vulnerable to user enumeration attacks.
#
# You can change it to a "required" module if you think it permits to
# guess valid user names of your system (invalid user names are considered
# as possibly being root on insecure lines), but root passwords may be
# communicated over insecure lines.
auth [success=ok new_authtok_reqd=ok ignore=ignore user_unknown=bad default=die] pam_securetty.so

# Disallows other than root logins when /etc/nologin exists
# (Replaces the `NOLOGINS_FILE' option from login.defs)
auth requisite pam_nologin.so

# SELinux needs to be the first session rule. This ensures that any
# lingering context has been cleared. Without this it is possible
# that a module could execute code in the wrong domain.
# When the module is present, "required" would be sufficient (When SELinux
# is disabled, this returns success.)
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close

# Sets the loginuid process attribute
session required pam_loginuid.so

# SELinux needs to intervene at login time to ensure that the process
# starts in the proper default security context. Only sessions which are
# intended to run in the user's context should be run after this.
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open
# When the module is present, "required" would be sufficient (When SELinux
# is disabled, this returns success.)

# This module parses environment configuration file(s)
# and also allows you to use an extended config
# file /etc/security/pam_env.conf.
#
# parsing /etc/environment needs "readenv=1"
session required pam_env.so readenv=1
# locale variables are also kept into /etc/default/locale in etch
# reading this file *in addition to /etc/environment* does not hurt
session required pam_env.so readenv=1 envfile=/etc/default/locale

# Standard Un*x authentication.
@include common-auth

# This allows certain extra groups to be granted to a user
# based on things like time of day, tty, service, and user.
# Please edit /etc/security/group.conf to fit your needs
# (Replaces the `CONSOLE_GROUPS' option in login.defs)
auth optional pam_group.so

# Uncomment and edit /etc/security/time.conf if you need to set
# time restraint on logins.
# (Replaces the `PORTTIME_CHECKS_ENAB' option from login.defs
# as well as /etc/porttime)
# account requisite pam_time.so

# Uncomment and edit /etc/security/access.conf if you need to
# set access limits.
# (Replaces /etc/login.access file)
# account required pam_access.so

# Sets up user limits according to /etc/security/limits.conf
# (Replaces the use of /etc/limits in old login)
session required pam_limits.so

# Prints the last login info upon successful login
# (Replaces the `LASTLOG_ENAB' option from login.defs)
session optional pam_lastlog.so

# Prints the message of the day upon successful login.
# (Replaces the `MOTD_FILE' option in login.defs)
# This includes a dynamically generated part from /run/motd.dynamic
# and a static (admin-editable) part from /etc/motd.
session optional pam_motd.so motd=/run/motd.dynamic
session optional pam_motd.so noupdate

# Prints the status of the user's mailbox upon successful login
# (Replaces the `MAIL_CHECK_ENAB' option from login.defs).
#
# This also defines the MAIL environment variable
# However, userdel also needs MAIL_DIR and MAIL_FILE variables
# in /etc/login.defs to make sure that removing a user
# also removes the user's mail spool file.
# See comments in /etc/login.defs
session optional pam_mail.so standard

# Create a new session keyring.
session optional pam_keyinit.so force revoke

# Standard Un*x account and session
@include common-account
@include common-session
@include common-password


If I replace my script with something like this:



#!/usr/bin/env python3
print('test')


motd works but when I try to use my cool motd I don't get any output.
Any idea why this happens? Where I can find some logs or something to find out why there is no output? I'm using Ubuntu 18.10 Server



Solved



/etc/update-motd.d/00:



#!/bin/zsh

export LANG='en_US.UTF-8'
/usr/bin/env python3 /etc/update-motd.d/00.py









share|improve this question
























  • did you have a look at the last post here? linuxquestions.org/questions/debian-26/…
    – db429
    Nov 26 at 21:21










  • hi did you also edit your /etc/pam.d/sshd to hold the line session optional pam_motd.so motd=/run/motd.dynamic ?
    – db429
    Nov 26 at 21:28










  • '/etc/pam.d/sshd ' pastebin.com/Sfmin3dL
    – I hate linux so much
    Nov 27 at 18:07













up vote
0
down vote

favorite









up vote
0
down vote

favorite











This is my 00-motd (-rwxr-xr-x) file:



#!/usr/bin/env python3

DISK_A = '/dev/sda2'
DISK_B = '/dev/sdb1'

import locale
locale.setlocale(locale.LC_TIME, 'pl_PL.UTF-8')

# https://github.com/maxogden/cool-ascii-faces
cool = [
u"( .-. )",
u"( .o.)",
u"( `·´ )",
u"( ° ͜ ʖ °)",
u"( ͡° ͜ʖ ͡°)",
u"( ⚆ _ ⚆ )",
u"( ︶︿︶)",
u"( ゚ヮ゚)",
u"(\/)(°,,,°)(\/)",
u"(¬_¬)",
u"(¬º-°)¬",
u"(¬‿¬)",
u"(°ロ°)☝",
u"(´・ω・)っ",
u"(ó ì_í)",
u"(ʘᗩʘ')",
u"(ʘ‿ʘ)",
u"(̿▀̿ ̿Ĺ̯̿̿▀̿ ̿)̄",
u"(͡° ͜ʖ ͡°)",
u"ᕦ( ͡° ͜ʖ ͡°)ᕤ",
u"(ಠ_ಠ)",
u"(ಠ‿ಠ)",
u"(ಠ⌣ಠ)",
u"(ಥ_ಥ)",
u"(ಥ﹏ಥ)",
u"(ง ͠° ͟ل͜ ͡°)ง",
u"(ง ͡ʘ ͜ʖ ͡ʘ)ง",
u"(ง •̀_•́)ง",
u"(ง'̀-'́)ง",
u"(ง°ل͜°)ง",
u"(ง⌐□ل͜□)ง",
u"(ღ˘⌣˘ღ)",
u"(ᵔᴥᵔ)",
u"(•ω•)",
u"(•◡•)/",
u"(⊙ω⊙)",
u"(⌐■_■)",
u"(─‿‿─)",
u"(╯°□°)╯",
u"(◕‿◕)",
u"(☞゚∀゚)☞",
u"(❍ᴥ❍ʋ)",
u"(っ◕‿◕)っ",
u"(づ。◕‿‿◕。)づ",
u"(ノಠ益ಠ)ノ",
u"(ノ・∀・)ノ",
u"(;一_一)",
u"(`◔ ω ◔´)",
u"(。◕‿‿◕。)",
u"(ノ◕ヮ◕)ノ",
u"*<{:¬{D}}}",
u"=^.^=",
u"t(-.-t)",
u"| (• ◡•)|",
u"~(˘▾˘~)",
u"¬_¬",
u"¯(°_o)/¯",
u"¯\_(ツ)_/¯",
u"°Д°",
u"ɳ༼ຈل͜ຈ༽ɲ",
u"ʅʕ•ᴥ•ʔʃ",
u"ʕ´•ᴥ•`ʔ",
u"ʕ•ᴥ•ʔ",
u"ʕ◉.◉ʔ",
u"ʕㅇ호ㅇʔ",
u"ʕ;•`ᴥ•´ʔ",
u"ʘ‿ʘ",
u"͡° ͜ʖ ͡°",
u"ζ༼Ɵ͆ل͜Ɵ͆༽ᶘ",
u"Ѱζ༼ᴼل͜ᴼ༽ᶘѰ",
u"ب_ب",
u"٩◔̯◔۶",
u"ಠ_ಠ",
u"ಠoಠ",
u"ಠ~ಠ",
u"ಠ‿ಠ",
u"ಠ⌣ಠ",
u"ಠ╭╮ಠ",
u"ರ_ರ",
u"ง ͠° ل͜ °)ง",
u"๏̯͡๏﴿",
u"༼ ºººººل͟ººººº ༽",
u"༼ ºل͟º ༽",
u"༼ ºل͟º༼",
u"༼ ºل͟º༽",
u"༼ ͡■ل͜ ͡■༽",
u"༼ つ ◕_◕ ༽つ",
u"༼ʘ̚ل͜ʘ̚༽",
u"ლ(´ڡ`ლ)",
u"ლ(́◉◞౪◟◉‵ლ)",
u"ლ(ಠ益ಠლ)",
u"ᄽὁȍ ̪őὀᄿ",
u"ᔑ•ﺪ͟͠•ᔐ",
u"ᕕ( ᐛ )ᕗ",
u"ᕙ(⇀‸↼‶)ᕗ",
u"ᕙ༼ຈل͜ຈ༽ᕗ",
u"ᶘ ᵒᴥᵒᶅ",
u"(ノಥ益ಥ)ノ",
u"≧☉_☉≦",
u"⊙▃⊙",
u"⊙﹏⊙",
u"┌( ಠ_ಠ)┘",
u"╚(ಠ_ಠ)=┐",
u"◉_◉",
u"◔ ⌣ ◔",
u"◔̯◔",
u"◕‿↼",
u"◕‿◕",
u"☉_☉",
u"☜(⌒▽⌒)☞",
u"☼.☼",
u"♥‿♥",
u"⚆ _ ⚆",
u"✌(-‿-)✌",
u"〆(・∀・@)",
u"ノ( º _ ºノ)",
u"ノ( ゜-゜ノ)",
u"ヽ( ͝° ͜ʖ͡°)ノ",
u"ヽ(`Д´)ノ",
u"ヽ༼° ͟ل͜ ͡°༽ノ",
u"ヽ༼ʘ̚ل͜ʘ̚༽ノ",
u"ヽ༼ຈل͜ຈ༽ง",
u"ヽ༼ຈل͜ຈ༽ノ",
u"ヽ༼Ὸل͜ຈ༽ノ",
u"ヾ(⌐■_■)ノ",
u"꒰・◡・๑꒱",
u"﴾͡๏̯͡๏﴿",
u"。◕‿◕。",
u"ʕノ◔ϖ◔ʔノ",
u"(ノಠ益ಠ)ノ彡┻━┻",
u"(╯°□°)╯︵ ┻━┻",
u"꒰•̥̥̥̥̥̥̥ ﹏ •̥̥̥̥̥̥̥̥๑꒱",
u"ಠ_ರೃ",
u"(ू˃̣̣̣̣̣̣︿˂̣̣̣̣̣̣ ू)",
u"(ꈨຶꎁꈨຶ)۶”",
u"(ꐦ°᷄д°᷅)",
u"(۶ૈ ۜ ᵒ̌▱๋ᵒ̌ )۶ૈ=͟͟͞͞ ⌨",
u"₍˄·͈༝·͈˄₎◞ ̑̑ෆ⃛",
u"(*゚⚙͠ ∀ ⚙͠)ノ❣",
u"٩꒰・ัε・ั ꒱۶",
u"ヘ(。□°)ヘ",
u"˓˓(ृ  ु ॑꒳’)ु(ृ’꒳ ॑ ृ )ु˒˒˒",
u"꒰✘Д✘◍꒱",
u"૮( ᵒ̌ૢཪᵒ̌ૢ )ა",
u"“ψ(`∇´)ψ",
u"ಠﭛಠ",
u"(๑>ᴗ<๑)",
u"(۶ꈨຶꎁꈨຶ )۶ʸᵉᵃʰᵎ",
u"٩(•̤̀ᵕ•̤́๑)ᵒᵏᵎᵎᵎᵎ",
u"(oT-T)尸",
u"(✌゚∀゚)☞",
u"ಥ‿ಥ",
u"ॱ॰⋆(˶ॢ‾᷄﹃‾᷅˵ॢ)",
u"┬┴┬┴┤ (ಠ├┬┴┬┴",
u"( ˘ ³˘)♥",
u"Σ (੭ु ຶਊ ຶ)੭ु⁾⁾",
u"(⑅ ॣ•͈ᴗ•͈ ॣ)",
u"ヾ(´¬`)ノ",
u"(•̀o•́)ง",
u"(๑•॒̀ ູ॒•́๑)",
u"⚈้̤͡ ˌ̫̮ ⚈้̤͡",
u"=͟͟͞͞ =͟͟͞͞ ヘ( ´Д`)ノ",
u"(((╹д╹;)))",
u"•̀.̫•́✧",
u"(ᵒ̤̑ ₀̑ ᵒ̤̑)",
u"\_(ʘ_ʘ)_/",
u"乙(ツ)乙",
u"乙(のっの)乙",
u"ヾ(¯∇ ̄๑)",
u"\_(ʘ_ʘ)_/",
u"༼;´༎ຶ ۝ ༎ຶ༽",
u"(▀̿Ĺ̯▀̿ ̿)",
u"(ノ◕ヮ◕)ノ*:・゚✧",
u"(ノ◕ヮ◕)ノ*:・゚✧ ✧゚・: *ヽ(◕ヮ◕ヽ)",
u"┬┴┬┴┤ ͜ʖ ͡°) ├┬┴┬┴",
u"┬┴┬┴┤(・_├┬┴┬┴",
u"(͡ ͡° ͜ つ ͡͡°)",
u"( ͡°╭͜ʖ╮͡° )",
u"(• ε •)",
u"[̲̅$̲̅(̲̅ ͡° ͜ʖ ͡°̲̅)̲̅$̲̅]",
u"| (• ◡•)| (❍ᴥ❍ʋ)",
u"(◕‿◕✿)",
u"(╯°□°)╯︵ ʞooqǝɔɐɟ",
u"(☞゚ヮ゚)☞ ☜(゚ヮ゚☜)",
u"(づ ̄ ³ ̄)づ",
u"(;´༎ຶД༎ຶ`)",
u"♪~ ᕕ(ᐛ)ᕗ",
u"༼ つ ͡° ͜ʖ ͡° ༽つ",
u"༼ つ ಥ_ಥ ༽つ",
u"ಥ_ಥ",
u"( ͡ᵔ ͜ʖ ͡ᵔ )",
u"ヾ(⌐■_■)ノ♪",
u"~(˘▾˘~)",
u"\ (•◡•) /",
u"(~˘▾˘)~",
u"(._.) ( l: ) ( .-. ) ( :l ) (._.)",
u"༼ ºل͟º ༼ ºل͟º ༼ ºل͟º ༽ ºل͟º ༽ ºل͟º ༽",
u"┻━┻ ︵ヽ(`Д´)ノ︵ ┻━┻",
u"ᕦ(ò_óˇ)ᕤ",
u"(•_•) ( •_•)>⌐■-■ (⌐■_■)",
u"(☞ຈل͜ຈ)☞",
u"˙ ͜ʟ˙",
u"☜(˚▽˚)☞",
u"(。◕‿◕。)",
u"(╯°□°)╯︵( .o.)",
u"(っ˘ڡ˘ς)",
u"┬──┬ ノ( ゜-゜ノ)",
u"ಠ⌣ಠ",
u"( ಠ ͜ʖರೃ)",
u"ƪ(˘⌣˘)ʃ",
u"¯\(°_o)/¯",
u"ლ,ᔑ•ﺪ͟͠•ᔐ.ლ",
u"(´・ω・`)",
u"(´・ω・)っ由",
u"(° ͡ ͜ ͡ʖ ͡ °)",
u"Ƹ̵̡Ӝ̵̨̄Ʒ",
u"ಠ_ಥ",
u"ಠ‿↼",
u"(>ლ)",
u"(▰˘◡˘▰)",
u"(✿´‿`)",
u"◔ ⌣ ◔",
u"。゜(`Д´)゜。",
u"┬─┬ノ( º _ ºノ)",
u"(ó ì_í)=óò=(ì_í ò)",
u"(/) (°,,°) (/)",
u"┬─┬ ︵ /(.□. )",
u"^̮^",
u"(>人<)",
u"(~_^)",
u"(・.◤)",
u">_>",
u"(^̮^)",
u"=U",
u"(。╹ω╹。)",
u"ლ(╹◡╹ლ)",
u"(●´⌓`●)",
u"([∂]ω[∂])",
u"U^エ^U",
u"(〒ó〒)",
u"(T^T)",
u"(íoì)",
u"(#•v•#)",
u"(•^u^•)",
u"!(^3^)!",
u"\(°°\”)",
u"(°o°:)",
u"(° o°)!",
u"(oロo)!!",
u"(òロó)",
u"(ò皿ó)",
u"( ̄・_______・ ̄)",
u"ヾ(๑╹◡╹)ノ'",
u"(ლ╹◡╹)ლ",
u"(◞‸◟)",
u"(✿◖◡◗)",
u"( ´・‿・`)",
u"(*`益´*)がう",
u"(ヾノ'д'o)ナィナィ",
u"❤(◕‿◕✿)",
u"(◡‿◡*)❤",
u"(o'ω'o)",
u"(。・ˇ_ˇ・。)ムゥ…",
u"♬♩♫♪☻(●´∀`●)☺♪♫♩♬",
u"(✿ฺ◕ฺ‿◕ฺ)ウフッ♥",
u"(つД⊂)エーン",
u"(つД・)チラ",
u"(*´ω`*)",
u"(✪‿✪)ノ",
u"╲(。◕‿◕。)╱",
u"ლ(^o^ლ)"
]

import random
r = random.SystemRandom()
cool_choice = r.choice(cool)

import time as t
time = t.strftime('%H:%M')
date = t.strftime('%A %d %B %Y').title()

import multiprocessing
cores = multiprocessing.cpu_count()

uptime = 0
idletime = 0
load = ''

with open('/proc/uptime', 'r') as f:
s = f.readline().split()
uptime = float(s[0])
idletime = float(s[1])

with open('/proc/loadavg', 'r') as f:
s = f.readline().split()
load = (s[0] + ', ' + s[1] + ', ' + s[2]).rjust(28, ' ')
processes = (s[3]).rjust(23, ' ')

import pendulum
uptime_for_humans = pendulum.duration(minutes=uptime // 60).in_words()
idle_percentage = '%.2f' % round(idletime / cores / uptime * 100, 2)

uptime_gui = uptime_for_humans + (idle_percentage + ' % idling').rjust(72 - len(uptime_for_humans), ' ')

import psutil
memory = psutil.virtual_memory()
partitions = psutil.disk_partitions()

disk_a_dev = '/'
disk_a = psutil.disk_usage('/')
disk_b_dev = '/'
disk_b = psutil.disk_usage('/')

for partition in partitions:
if DISK_A == partition.device:
disk_a_dev = partition.device
disk_a = psutil.disk_usage(partition.mountpoint)
if DISK_B == partition.device:
disk_b_dev = partition.device
disk_b = psutil.disk_usage(partition.mountpoint)

def bytes_for_humans(b, ndigits=2):
units = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'] # Powodzenia kurwa
depth = 0
value = b

while (value // 1024):
depth += 1
value /= 1024

if depth:
value = ('%.2f' % round(value, ndigits))

return str(value) + ' ' + units[depth]

disk_a_data = [
('%.2f' % round(disk_a.used / disk_a.total * 100, 2)).rjust(32 - len(disk_a_dev), ' '),
bytes_for_humans(disk_a.total).rjust(27, ' '),
bytes_for_humans(disk_a.free).rjust(27, ' '),
bytes_for_humans(disk_a.used).rjust(27, ' ')
]

disk_b_data = [
('%.2f' % round(disk_b.used / disk_b.total * 100, 2)).rjust(32 - len(disk_b_dev), ' '),
bytes_for_humans(disk_b.total).rjust(27, ' '),
bytes_for_humans(disk_b.free).rjust(27, ' '),
bytes_for_humans(disk_b.used).rjust(27, ' ')
]

mem_data = [
('%.2f' % round(memory.used / memory.total * 100, 2)).rjust(20, ' '),
bytes_for_humans(memory.total).rjust(23, ' '),
bytes_for_humans(memory.available).rjust(23, ' '),
bytes_for_humans(memory.free).rjust(23, ' '),
bytes_for_humans(memory.used).rjust(23, ' ')
]

print(f'''
┌─┐┬ ┬┌┐ ┌─┐┬─┐┌─┐┌─┐┬ ┬┬┬
└─┐│ │├┴┐├─┤├┬┘├─┤└─┐├─┤││ {time}
└─┘└─┘└─┘┴ ┴┴└─┴ ┴└─┘┴ ┴┴┴ {date}

{cool_choice}


┌ Uptime ──────────────────────────────────────────────────────────────────┐
│ {uptime_gui } │
└──────────────────────────────────────────────────────────────────────────┘
┌ System ────────────────────────────┐┌ Partitions ────────────────────────┐
│ Load: {load } ││ {disk_a_dev + disk_a_data[0] } % │
│ Processes: {processes } ││ Total: {disk_a_data[1] } │
└────────────────────────────────────┘│ Free: {disk_a_data[2] } │
┌ Memory ────────────────────────────┐│ Used: {disk_a_data[3] } │
│ Percentage: {mem_data[0] } % │├────────────────────────────────────┤
│ Total: {mem_data[1] } ││ {disk_b_dev + disk_b_data[0] } % │
│ Available: {mem_data[2] } ││ Total: {disk_b_data[1] } │
│ Free: {mem_data[3] } ││ Free: {disk_b_data[2] } │
│ Used: {mem_data[4] } ││ Used: {disk_b_data[3] } │
└────────────────────────────────────┘└────────────────────────────────────┘
''')


This is output of run-parts /etc/update-motd.d:



run-parts output



This is /etc/pam.d/login:



#
# The PAM configuration file for the Shadow `login' service
#

# Enforce a minimal delay in case of failure (in microseconds).
# (Replaces the `FAIL_DELAY' setting from login.defs)
# Note that other modules may require another minimal delay. (for example,
# to disable any delay, you should add the nodelay option to pam_unix)
auth optional pam_faildelay.so delay=3000000

# Outputs an issue file prior to each login prompt (Replaces the
# ISSUE_FILE option from login.defs). Uncomment for use
# auth required pam_issue.so issue=/etc/issue

# Disallows root logins except on tty's listed in /etc/securetty
# (Replaces the `CONSOLE' setting from login.defs)
#
# With the default control of this module:
# [success=ok new_authtok_reqd=ok ignore=ignore user_unknown=bad default=die]
# root will not be prompted for a password on insecure lines.
# if an invalid username is entered, a password is prompted (but login
# will eventually be rejected)
#
# You can change it to a "requisite" module if you think root may mis-type
# her login and should not be prompted for a password in that case. But
# this will leave the system as vulnerable to user enumeration attacks.
#
# You can change it to a "required" module if you think it permits to
# guess valid user names of your system (invalid user names are considered
# as possibly being root on insecure lines), but root passwords may be
# communicated over insecure lines.
auth [success=ok new_authtok_reqd=ok ignore=ignore user_unknown=bad default=die] pam_securetty.so

# Disallows other than root logins when /etc/nologin exists
# (Replaces the `NOLOGINS_FILE' option from login.defs)
auth requisite pam_nologin.so

# SELinux needs to be the first session rule. This ensures that any
# lingering context has been cleared. Without this it is possible
# that a module could execute code in the wrong domain.
# When the module is present, "required" would be sufficient (When SELinux
# is disabled, this returns success.)
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close

# Sets the loginuid process attribute
session required pam_loginuid.so

# SELinux needs to intervene at login time to ensure that the process
# starts in the proper default security context. Only sessions which are
# intended to run in the user's context should be run after this.
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open
# When the module is present, "required" would be sufficient (When SELinux
# is disabled, this returns success.)

# This module parses environment configuration file(s)
# and also allows you to use an extended config
# file /etc/security/pam_env.conf.
#
# parsing /etc/environment needs "readenv=1"
session required pam_env.so readenv=1
# locale variables are also kept into /etc/default/locale in etch
# reading this file *in addition to /etc/environment* does not hurt
session required pam_env.so readenv=1 envfile=/etc/default/locale

# Standard Un*x authentication.
@include common-auth

# This allows certain extra groups to be granted to a user
# based on things like time of day, tty, service, and user.
# Please edit /etc/security/group.conf to fit your needs
# (Replaces the `CONSOLE_GROUPS' option in login.defs)
auth optional pam_group.so

# Uncomment and edit /etc/security/time.conf if you need to set
# time restraint on logins.
# (Replaces the `PORTTIME_CHECKS_ENAB' option from login.defs
# as well as /etc/porttime)
# account requisite pam_time.so

# Uncomment and edit /etc/security/access.conf if you need to
# set access limits.
# (Replaces /etc/login.access file)
# account required pam_access.so

# Sets up user limits according to /etc/security/limits.conf
# (Replaces the use of /etc/limits in old login)
session required pam_limits.so

# Prints the last login info upon successful login
# (Replaces the `LASTLOG_ENAB' option from login.defs)
session optional pam_lastlog.so

# Prints the message of the day upon successful login.
# (Replaces the `MOTD_FILE' option in login.defs)
# This includes a dynamically generated part from /run/motd.dynamic
# and a static (admin-editable) part from /etc/motd.
session optional pam_motd.so motd=/run/motd.dynamic
session optional pam_motd.so noupdate

# Prints the status of the user's mailbox upon successful login
# (Replaces the `MAIL_CHECK_ENAB' option from login.defs).
#
# This also defines the MAIL environment variable
# However, userdel also needs MAIL_DIR and MAIL_FILE variables
# in /etc/login.defs to make sure that removing a user
# also removes the user's mail spool file.
# See comments in /etc/login.defs
session optional pam_mail.so standard

# Create a new session keyring.
session optional pam_keyinit.so force revoke

# Standard Un*x account and session
@include common-account
@include common-session
@include common-password


If I replace my script with something like this:



#!/usr/bin/env python3
print('test')


motd works but when I try to use my cool motd I don't get any output.
Any idea why this happens? Where I can find some logs or something to find out why there is no output? I'm using Ubuntu 18.10 Server



Solved



/etc/update-motd.d/00:



#!/bin/zsh

export LANG='en_US.UTF-8'
/usr/bin/env python3 /etc/update-motd.d/00.py









share|improve this question















This is my 00-motd (-rwxr-xr-x) file:



#!/usr/bin/env python3

DISK_A = '/dev/sda2'
DISK_B = '/dev/sdb1'

import locale
locale.setlocale(locale.LC_TIME, 'pl_PL.UTF-8')

# https://github.com/maxogden/cool-ascii-faces
cool = [
u"( .-. )",
u"( .o.)",
u"( `·´ )",
u"( ° ͜ ʖ °)",
u"( ͡° ͜ʖ ͡°)",
u"( ⚆ _ ⚆ )",
u"( ︶︿︶)",
u"( ゚ヮ゚)",
u"(\/)(°,,,°)(\/)",
u"(¬_¬)",
u"(¬º-°)¬",
u"(¬‿¬)",
u"(°ロ°)☝",
u"(´・ω・)っ",
u"(ó ì_í)",
u"(ʘᗩʘ')",
u"(ʘ‿ʘ)",
u"(̿▀̿ ̿Ĺ̯̿̿▀̿ ̿)̄",
u"(͡° ͜ʖ ͡°)",
u"ᕦ( ͡° ͜ʖ ͡°)ᕤ",
u"(ಠ_ಠ)",
u"(ಠ‿ಠ)",
u"(ಠ⌣ಠ)",
u"(ಥ_ಥ)",
u"(ಥ﹏ಥ)",
u"(ง ͠° ͟ل͜ ͡°)ง",
u"(ง ͡ʘ ͜ʖ ͡ʘ)ง",
u"(ง •̀_•́)ง",
u"(ง'̀-'́)ง",
u"(ง°ل͜°)ง",
u"(ง⌐□ل͜□)ง",
u"(ღ˘⌣˘ღ)",
u"(ᵔᴥᵔ)",
u"(•ω•)",
u"(•◡•)/",
u"(⊙ω⊙)",
u"(⌐■_■)",
u"(─‿‿─)",
u"(╯°□°)╯",
u"(◕‿◕)",
u"(☞゚∀゚)☞",
u"(❍ᴥ❍ʋ)",
u"(っ◕‿◕)っ",
u"(づ。◕‿‿◕。)づ",
u"(ノಠ益ಠ)ノ",
u"(ノ・∀・)ノ",
u"(;一_一)",
u"(`◔ ω ◔´)",
u"(。◕‿‿◕。)",
u"(ノ◕ヮ◕)ノ",
u"*<{:¬{D}}}",
u"=^.^=",
u"t(-.-t)",
u"| (• ◡•)|",
u"~(˘▾˘~)",
u"¬_¬",
u"¯(°_o)/¯",
u"¯\_(ツ)_/¯",
u"°Д°",
u"ɳ༼ຈل͜ຈ༽ɲ",
u"ʅʕ•ᴥ•ʔʃ",
u"ʕ´•ᴥ•`ʔ",
u"ʕ•ᴥ•ʔ",
u"ʕ◉.◉ʔ",
u"ʕㅇ호ㅇʔ",
u"ʕ;•`ᴥ•´ʔ",
u"ʘ‿ʘ",
u"͡° ͜ʖ ͡°",
u"ζ༼Ɵ͆ل͜Ɵ͆༽ᶘ",
u"Ѱζ༼ᴼل͜ᴼ༽ᶘѰ",
u"ب_ب",
u"٩◔̯◔۶",
u"ಠ_ಠ",
u"ಠoಠ",
u"ಠ~ಠ",
u"ಠ‿ಠ",
u"ಠ⌣ಠ",
u"ಠ╭╮ಠ",
u"ರ_ರ",
u"ง ͠° ل͜ °)ง",
u"๏̯͡๏﴿",
u"༼ ºººººل͟ººººº ༽",
u"༼ ºل͟º ༽",
u"༼ ºل͟º༼",
u"༼ ºل͟º༽",
u"༼ ͡■ل͜ ͡■༽",
u"༼ つ ◕_◕ ༽つ",
u"༼ʘ̚ل͜ʘ̚༽",
u"ლ(´ڡ`ლ)",
u"ლ(́◉◞౪◟◉‵ლ)",
u"ლ(ಠ益ಠლ)",
u"ᄽὁȍ ̪őὀᄿ",
u"ᔑ•ﺪ͟͠•ᔐ",
u"ᕕ( ᐛ )ᕗ",
u"ᕙ(⇀‸↼‶)ᕗ",
u"ᕙ༼ຈل͜ຈ༽ᕗ",
u"ᶘ ᵒᴥᵒᶅ",
u"(ノಥ益ಥ)ノ",
u"≧☉_☉≦",
u"⊙▃⊙",
u"⊙﹏⊙",
u"┌( ಠ_ಠ)┘",
u"╚(ಠ_ಠ)=┐",
u"◉_◉",
u"◔ ⌣ ◔",
u"◔̯◔",
u"◕‿↼",
u"◕‿◕",
u"☉_☉",
u"☜(⌒▽⌒)☞",
u"☼.☼",
u"♥‿♥",
u"⚆ _ ⚆",
u"✌(-‿-)✌",
u"〆(・∀・@)",
u"ノ( º _ ºノ)",
u"ノ( ゜-゜ノ)",
u"ヽ( ͝° ͜ʖ͡°)ノ",
u"ヽ(`Д´)ノ",
u"ヽ༼° ͟ل͜ ͡°༽ノ",
u"ヽ༼ʘ̚ل͜ʘ̚༽ノ",
u"ヽ༼ຈل͜ຈ༽ง",
u"ヽ༼ຈل͜ຈ༽ノ",
u"ヽ༼Ὸل͜ຈ༽ノ",
u"ヾ(⌐■_■)ノ",
u"꒰・◡・๑꒱",
u"﴾͡๏̯͡๏﴿",
u"。◕‿◕。",
u"ʕノ◔ϖ◔ʔノ",
u"(ノಠ益ಠ)ノ彡┻━┻",
u"(╯°□°)╯︵ ┻━┻",
u"꒰•̥̥̥̥̥̥̥ ﹏ •̥̥̥̥̥̥̥̥๑꒱",
u"ಠ_ರೃ",
u"(ू˃̣̣̣̣̣̣︿˂̣̣̣̣̣̣ ू)",
u"(ꈨຶꎁꈨຶ)۶”",
u"(ꐦ°᷄д°᷅)",
u"(۶ૈ ۜ ᵒ̌▱๋ᵒ̌ )۶ૈ=͟͟͞͞ ⌨",
u"₍˄·͈༝·͈˄₎◞ ̑̑ෆ⃛",
u"(*゚⚙͠ ∀ ⚙͠)ノ❣",
u"٩꒰・ัε・ั ꒱۶",
u"ヘ(。□°)ヘ",
u"˓˓(ृ  ु ॑꒳’)ु(ृ’꒳ ॑ ृ )ु˒˒˒",
u"꒰✘Д✘◍꒱",
u"૮( ᵒ̌ૢཪᵒ̌ૢ )ა",
u"“ψ(`∇´)ψ",
u"ಠﭛಠ",
u"(๑>ᴗ<๑)",
u"(۶ꈨຶꎁꈨຶ )۶ʸᵉᵃʰᵎ",
u"٩(•̤̀ᵕ•̤́๑)ᵒᵏᵎᵎᵎᵎ",
u"(oT-T)尸",
u"(✌゚∀゚)☞",
u"ಥ‿ಥ",
u"ॱ॰⋆(˶ॢ‾᷄﹃‾᷅˵ॢ)",
u"┬┴┬┴┤ (ಠ├┬┴┬┴",
u"( ˘ ³˘)♥",
u"Σ (੭ु ຶਊ ຶ)੭ु⁾⁾",
u"(⑅ ॣ•͈ᴗ•͈ ॣ)",
u"ヾ(´¬`)ノ",
u"(•̀o•́)ง",
u"(๑•॒̀ ູ॒•́๑)",
u"⚈้̤͡ ˌ̫̮ ⚈้̤͡",
u"=͟͟͞͞ =͟͟͞͞ ヘ( ´Д`)ノ",
u"(((╹д╹;)))",
u"•̀.̫•́✧",
u"(ᵒ̤̑ ₀̑ ᵒ̤̑)",
u"\_(ʘ_ʘ)_/",
u"乙(ツ)乙",
u"乙(のっの)乙",
u"ヾ(¯∇ ̄๑)",
u"\_(ʘ_ʘ)_/",
u"༼;´༎ຶ ۝ ༎ຶ༽",
u"(▀̿Ĺ̯▀̿ ̿)",
u"(ノ◕ヮ◕)ノ*:・゚✧",
u"(ノ◕ヮ◕)ノ*:・゚✧ ✧゚・: *ヽ(◕ヮ◕ヽ)",
u"┬┴┬┴┤ ͜ʖ ͡°) ├┬┴┬┴",
u"┬┴┬┴┤(・_├┬┴┬┴",
u"(͡ ͡° ͜ つ ͡͡°)",
u"( ͡°╭͜ʖ╮͡° )",
u"(• ε •)",
u"[̲̅$̲̅(̲̅ ͡° ͜ʖ ͡°̲̅)̲̅$̲̅]",
u"| (• ◡•)| (❍ᴥ❍ʋ)",
u"(◕‿◕✿)",
u"(╯°□°)╯︵ ʞooqǝɔɐɟ",
u"(☞゚ヮ゚)☞ ☜(゚ヮ゚☜)",
u"(づ ̄ ³ ̄)づ",
u"(;´༎ຶД༎ຶ`)",
u"♪~ ᕕ(ᐛ)ᕗ",
u"༼ つ ͡° ͜ʖ ͡° ༽つ",
u"༼ つ ಥ_ಥ ༽つ",
u"ಥ_ಥ",
u"( ͡ᵔ ͜ʖ ͡ᵔ )",
u"ヾ(⌐■_■)ノ♪",
u"~(˘▾˘~)",
u"\ (•◡•) /",
u"(~˘▾˘)~",
u"(._.) ( l: ) ( .-. ) ( :l ) (._.)",
u"༼ ºل͟º ༼ ºل͟º ༼ ºل͟º ༽ ºل͟º ༽ ºل͟º ༽",
u"┻━┻ ︵ヽ(`Д´)ノ︵ ┻━┻",
u"ᕦ(ò_óˇ)ᕤ",
u"(•_•) ( •_•)>⌐■-■ (⌐■_■)",
u"(☞ຈل͜ຈ)☞",
u"˙ ͜ʟ˙",
u"☜(˚▽˚)☞",
u"(。◕‿◕。)",
u"(╯°□°)╯︵( .o.)",
u"(っ˘ڡ˘ς)",
u"┬──┬ ノ( ゜-゜ノ)",
u"ಠ⌣ಠ",
u"( ಠ ͜ʖರೃ)",
u"ƪ(˘⌣˘)ʃ",
u"¯\(°_o)/¯",
u"ლ,ᔑ•ﺪ͟͠•ᔐ.ლ",
u"(´・ω・`)",
u"(´・ω・)っ由",
u"(° ͡ ͜ ͡ʖ ͡ °)",
u"Ƹ̵̡Ӝ̵̨̄Ʒ",
u"ಠ_ಥ",
u"ಠ‿↼",
u"(>ლ)",
u"(▰˘◡˘▰)",
u"(✿´‿`)",
u"◔ ⌣ ◔",
u"。゜(`Д´)゜。",
u"┬─┬ノ( º _ ºノ)",
u"(ó ì_í)=óò=(ì_í ò)",
u"(/) (°,,°) (/)",
u"┬─┬ ︵ /(.□. )",
u"^̮^",
u"(>人<)",
u"(~_^)",
u"(・.◤)",
u">_>",
u"(^̮^)",
u"=U",
u"(。╹ω╹。)",
u"ლ(╹◡╹ლ)",
u"(●´⌓`●)",
u"([∂]ω[∂])",
u"U^エ^U",
u"(〒ó〒)",
u"(T^T)",
u"(íoì)",
u"(#•v•#)",
u"(•^u^•)",
u"!(^3^)!",
u"\(°°\”)",
u"(°o°:)",
u"(° o°)!",
u"(oロo)!!",
u"(òロó)",
u"(ò皿ó)",
u"( ̄・_______・ ̄)",
u"ヾ(๑╹◡╹)ノ'",
u"(ლ╹◡╹)ლ",
u"(◞‸◟)",
u"(✿◖◡◗)",
u"( ´・‿・`)",
u"(*`益´*)がう",
u"(ヾノ'д'o)ナィナィ",
u"❤(◕‿◕✿)",
u"(◡‿◡*)❤",
u"(o'ω'o)",
u"(。・ˇ_ˇ・。)ムゥ…",
u"♬♩♫♪☻(●´∀`●)☺♪♫♩♬",
u"(✿ฺ◕ฺ‿◕ฺ)ウフッ♥",
u"(つД⊂)エーン",
u"(つД・)チラ",
u"(*´ω`*)",
u"(✪‿✪)ノ",
u"╲(。◕‿◕。)╱",
u"ლ(^o^ლ)"
]

import random
r = random.SystemRandom()
cool_choice = r.choice(cool)

import time as t
time = t.strftime('%H:%M')
date = t.strftime('%A %d %B %Y').title()

import multiprocessing
cores = multiprocessing.cpu_count()

uptime = 0
idletime = 0
load = ''

with open('/proc/uptime', 'r') as f:
s = f.readline().split()
uptime = float(s[0])
idletime = float(s[1])

with open('/proc/loadavg', 'r') as f:
s = f.readline().split()
load = (s[0] + ', ' + s[1] + ', ' + s[2]).rjust(28, ' ')
processes = (s[3]).rjust(23, ' ')

import pendulum
uptime_for_humans = pendulum.duration(minutes=uptime // 60).in_words()
idle_percentage = '%.2f' % round(idletime / cores / uptime * 100, 2)

uptime_gui = uptime_for_humans + (idle_percentage + ' % idling').rjust(72 - len(uptime_for_humans), ' ')

import psutil
memory = psutil.virtual_memory()
partitions = psutil.disk_partitions()

disk_a_dev = '/'
disk_a = psutil.disk_usage('/')
disk_b_dev = '/'
disk_b = psutil.disk_usage('/')

for partition in partitions:
if DISK_A == partition.device:
disk_a_dev = partition.device
disk_a = psutil.disk_usage(partition.mountpoint)
if DISK_B == partition.device:
disk_b_dev = partition.device
disk_b = psutil.disk_usage(partition.mountpoint)

def bytes_for_humans(b, ndigits=2):
units = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'] # Powodzenia kurwa
depth = 0
value = b

while (value // 1024):
depth += 1
value /= 1024

if depth:
value = ('%.2f' % round(value, ndigits))

return str(value) + ' ' + units[depth]

disk_a_data = [
('%.2f' % round(disk_a.used / disk_a.total * 100, 2)).rjust(32 - len(disk_a_dev), ' '),
bytes_for_humans(disk_a.total).rjust(27, ' '),
bytes_for_humans(disk_a.free).rjust(27, ' '),
bytes_for_humans(disk_a.used).rjust(27, ' ')
]

disk_b_data = [
('%.2f' % round(disk_b.used / disk_b.total * 100, 2)).rjust(32 - len(disk_b_dev), ' '),
bytes_for_humans(disk_b.total).rjust(27, ' '),
bytes_for_humans(disk_b.free).rjust(27, ' '),
bytes_for_humans(disk_b.used).rjust(27, ' ')
]

mem_data = [
('%.2f' % round(memory.used / memory.total * 100, 2)).rjust(20, ' '),
bytes_for_humans(memory.total).rjust(23, ' '),
bytes_for_humans(memory.available).rjust(23, ' '),
bytes_for_humans(memory.free).rjust(23, ' '),
bytes_for_humans(memory.used).rjust(23, ' ')
]

print(f'''
┌─┐┬ ┬┌┐ ┌─┐┬─┐┌─┐┌─┐┬ ┬┬┬
└─┐│ │├┴┐├─┤├┬┘├─┤└─┐├─┤││ {time}
└─┘└─┘└─┘┴ ┴┴└─┴ ┴└─┘┴ ┴┴┴ {date}

{cool_choice}


┌ Uptime ──────────────────────────────────────────────────────────────────┐
│ {uptime_gui } │
└──────────────────────────────────────────────────────────────────────────┘
┌ System ────────────────────────────┐┌ Partitions ────────────────────────┐
│ Load: {load } ││ {disk_a_dev + disk_a_data[0] } % │
│ Processes: {processes } ││ Total: {disk_a_data[1] } │
└────────────────────────────────────┘│ Free: {disk_a_data[2] } │
┌ Memory ────────────────────────────┐│ Used: {disk_a_data[3] } │
│ Percentage: {mem_data[0] } % │├────────────────────────────────────┤
│ Total: {mem_data[1] } ││ {disk_b_dev + disk_b_data[0] } % │
│ Available: {mem_data[2] } ││ Total: {disk_b_data[1] } │
│ Free: {mem_data[3] } ││ Free: {disk_b_data[2] } │
│ Used: {mem_data[4] } ││ Used: {disk_b_data[3] } │
└────────────────────────────────────┘└────────────────────────────────────┘
''')


This is output of run-parts /etc/update-motd.d:



run-parts output



This is /etc/pam.d/login:



#
# The PAM configuration file for the Shadow `login' service
#

# Enforce a minimal delay in case of failure (in microseconds).
# (Replaces the `FAIL_DELAY' setting from login.defs)
# Note that other modules may require another minimal delay. (for example,
# to disable any delay, you should add the nodelay option to pam_unix)
auth optional pam_faildelay.so delay=3000000

# Outputs an issue file prior to each login prompt (Replaces the
# ISSUE_FILE option from login.defs). Uncomment for use
# auth required pam_issue.so issue=/etc/issue

# Disallows root logins except on tty's listed in /etc/securetty
# (Replaces the `CONSOLE' setting from login.defs)
#
# With the default control of this module:
# [success=ok new_authtok_reqd=ok ignore=ignore user_unknown=bad default=die]
# root will not be prompted for a password on insecure lines.
# if an invalid username is entered, a password is prompted (but login
# will eventually be rejected)
#
# You can change it to a "requisite" module if you think root may mis-type
# her login and should not be prompted for a password in that case. But
# this will leave the system as vulnerable to user enumeration attacks.
#
# You can change it to a "required" module if you think it permits to
# guess valid user names of your system (invalid user names are considered
# as possibly being root on insecure lines), but root passwords may be
# communicated over insecure lines.
auth [success=ok new_authtok_reqd=ok ignore=ignore user_unknown=bad default=die] pam_securetty.so

# Disallows other than root logins when /etc/nologin exists
# (Replaces the `NOLOGINS_FILE' option from login.defs)
auth requisite pam_nologin.so

# SELinux needs to be the first session rule. This ensures that any
# lingering context has been cleared. Without this it is possible
# that a module could execute code in the wrong domain.
# When the module is present, "required" would be sufficient (When SELinux
# is disabled, this returns success.)
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close

# Sets the loginuid process attribute
session required pam_loginuid.so

# SELinux needs to intervene at login time to ensure that the process
# starts in the proper default security context. Only sessions which are
# intended to run in the user's context should be run after this.
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open
# When the module is present, "required" would be sufficient (When SELinux
# is disabled, this returns success.)

# This module parses environment configuration file(s)
# and also allows you to use an extended config
# file /etc/security/pam_env.conf.
#
# parsing /etc/environment needs "readenv=1"
session required pam_env.so readenv=1
# locale variables are also kept into /etc/default/locale in etch
# reading this file *in addition to /etc/environment* does not hurt
session required pam_env.so readenv=1 envfile=/etc/default/locale

# Standard Un*x authentication.
@include common-auth

# This allows certain extra groups to be granted to a user
# based on things like time of day, tty, service, and user.
# Please edit /etc/security/group.conf to fit your needs
# (Replaces the `CONSOLE_GROUPS' option in login.defs)
auth optional pam_group.so

# Uncomment and edit /etc/security/time.conf if you need to set
# time restraint on logins.
# (Replaces the `PORTTIME_CHECKS_ENAB' option from login.defs
# as well as /etc/porttime)
# account requisite pam_time.so

# Uncomment and edit /etc/security/access.conf if you need to
# set access limits.
# (Replaces /etc/login.access file)
# account required pam_access.so

# Sets up user limits according to /etc/security/limits.conf
# (Replaces the use of /etc/limits in old login)
session required pam_limits.so

# Prints the last login info upon successful login
# (Replaces the `LASTLOG_ENAB' option from login.defs)
session optional pam_lastlog.so

# Prints the message of the day upon successful login.
# (Replaces the `MOTD_FILE' option in login.defs)
# This includes a dynamically generated part from /run/motd.dynamic
# and a static (admin-editable) part from /etc/motd.
session optional pam_motd.so motd=/run/motd.dynamic
session optional pam_motd.so noupdate

# Prints the status of the user's mailbox upon successful login
# (Replaces the `MAIL_CHECK_ENAB' option from login.defs).
#
# This also defines the MAIL environment variable
# However, userdel also needs MAIL_DIR and MAIL_FILE variables
# in /etc/login.defs to make sure that removing a user
# also removes the user's mail spool file.
# See comments in /etc/login.defs
session optional pam_mail.so standard

# Create a new session keyring.
session optional pam_keyinit.so force revoke

# Standard Un*x account and session
@include common-account
@include common-session
@include common-password


If I replace my script with something like this:



#!/usr/bin/env python3
print('test')


motd works but when I try to use my cool motd I don't get any output.
Any idea why this happens? Where I can find some logs or something to find out why there is no output? I'm using Ubuntu 18.10 Server



Solved



/etc/update-motd.d/00:



#!/bin/zsh

export LANG='en_US.UTF-8'
/usr/bin/env python3 /etc/update-motd.d/00.py






motd






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 28 at 19:41

























asked Nov 26 at 18:35









I hate linux so much

11




11












  • did you have a look at the last post here? linuxquestions.org/questions/debian-26/…
    – db429
    Nov 26 at 21:21










  • hi did you also edit your /etc/pam.d/sshd to hold the line session optional pam_motd.so motd=/run/motd.dynamic ?
    – db429
    Nov 26 at 21:28










  • '/etc/pam.d/sshd ' pastebin.com/Sfmin3dL
    – I hate linux so much
    Nov 27 at 18:07


















  • did you have a look at the last post here? linuxquestions.org/questions/debian-26/…
    – db429
    Nov 26 at 21:21










  • hi did you also edit your /etc/pam.d/sshd to hold the line session optional pam_motd.so motd=/run/motd.dynamic ?
    – db429
    Nov 26 at 21:28










  • '/etc/pam.d/sshd ' pastebin.com/Sfmin3dL
    – I hate linux so much
    Nov 27 at 18:07
















did you have a look at the last post here? linuxquestions.org/questions/debian-26/…
– db429
Nov 26 at 21:21




did you have a look at the last post here? linuxquestions.org/questions/debian-26/…
– db429
Nov 26 at 21:21












hi did you also edit your /etc/pam.d/sshd to hold the line session optional pam_motd.so motd=/run/motd.dynamic ?
– db429
Nov 26 at 21:28




hi did you also edit your /etc/pam.d/sshd to hold the line session optional pam_motd.so motd=/run/motd.dynamic ?
– db429
Nov 26 at 21:28












'/etc/pam.d/sshd ' pastebin.com/Sfmin3dL
– I hate linux so much
Nov 27 at 18:07




'/etc/pam.d/sshd ' pastebin.com/Sfmin3dL
– I hate linux so much
Nov 27 at 18:07















active

oldest

votes











Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "89"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1096259%2fmy-motd-script-works-using-run-parts-but-no-output-when-i-log-in-via-ssh%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown






























active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Ask Ubuntu!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1096259%2fmy-motd-script-works-using-run-parts-but-no-output-when-i-log-in-via-ssh%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

ComboBox Display Member on multiple fields

Is it possible to collect Nectar points via Trainline?