Bashblog v1.0 0 - cria um microblog em HTML5
Publicado por Raphael Ciribelly (última atualização em 03/12/2020)
[ Hits: 2.488 ]
Cria um microblog em HTML5.
Dar permissão de execução ao script:
$ chmod +x bashblog.sh
Chama a função help mostrando como utilizar:
$ ./bashblog
#!/bin/bash # bashblog v1.0 # Size: 20340 bytes # Date: 2020-11-17 # OS: Debian GNU/Linux 10 (buster) # bash version: GNU bash, versão 5.0.3(1)-release (x86_64-pc-linux-gnu) # sed version: sed (GNU sed) 4.7 # grep version: grep (GNU grep) 3.3 # vim version: VIM - Vi IMproved 8.1 # touch version: touch (GNU coreutils) 8.30 # mkdir version: mkdir (GNU coreutils) 8.30 # rm version: rm (GNU coreutils) 8.30 # rmdir version: rmdir (GNU coreutils) 8.30 # Variables - set the names inside the double quotes, CONFIGURE! SITE_NAME="Name Site" SITE_LINK="https://www.Site.com" MENU_NAME_1="Home" MENU_NAME_2="About" MENU_NAME_3="Blog" MENU_NAME_4="Downloads" MENU_NAME_5="Email" MENU_LINK_1="index.html" MENU_LINK_2="about.html" MENU_LINK_3="blog.html" MENU_LINK_4='downloads.html' MENU_LINK_5="mailto:contact@email.com" SOCIAL_NAME_1="Facebook" SOCIAL_NAME_2="Instagram" SOCIAL_NAME_3="YouTube" SOCIAL_LINK_1="link facebook" SOCIAL_LINK_2="link instagram" SOCIAL_LINK_3="link youtube" # Variables - path of files and directories DIR_SITE="${HOME}/Site" DIR_POST="${HOME}/Site/post" DIR_CSS="${HOME}/Site/css" DIR_IMG="${HOME}/Site/img" DIR_FILES="${HOME}/Site/files" INDEXHTML="${HOME}/Site/${MENU_LINK_1}" ABOUTHTML="${HOME}/Site/${MENU_LINK_2}" BLOGHTML="${HOME}/Site/${MENU_LINK_3}" DOWNLOADSHTML="${HOME}/Site/${MENU_LINK_4}" STYLE_CSS="${HOME}/Site/css/style.css" NORMALIZE_CSS="${HOME}/Site/css/normalize.css" EDITOR="vim" # checks if files exist CHECK_FILES(){ for i in ${DIR_SITE} ${DIR_POST} ${DIR_CSS} ${DIR_IMG} ${DIR_FILES} ${INDEXHTML} ${ABOUTHTML} ${BLOGHTML} ${DOWNLOADSHTML} ${STYLE_CSS} ${NORMALIZE_CSS};do [[ ! -e "${i}" ]] && { echo "$i Does not exist." ; exit 1 ; } done } BASE_HTML(){ # index.html if [[ ! -e "${INDEXHTML}" ]] ; then cat <<EOF > "${INDEXHTML}" <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Home | ${SITE_NAME}</title> <meta name="robots" content="index, follow" /> <meta name="googlebot" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1" /> <meta name="bingbot" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1" /> <meta name="keywords" content="index, ${SITE_NAME}"/> <link rel="canonical" href="${SITE_LINK}/${MENU_LINK_1}" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" type="text/css" href="css/normalize.css"> <link rel="stylesheet" type="text/css" href="css/style.css"> </head> <body> <header class="header"> <h1 class="logo">${SITE_NAME}</h1> <nav class="menu"> <ul class="menu_ul"> <li><a class="active" href="${MENU_LINK_1}">${MENU_NAME_1}</a></li> <li><a href="${MENU_LINK_2}">${MENU_NAME_2}</a></li> <li><a href="${MENU_LINK_3}">${MENU_NAME_3}</a></li> <li><a href="${MENU_LINK_4}">${MENU_NAME_4}</a></li> <li><a href="${MENU_LINK_5}">${MENU_NAME_5}</a></li> </ul> </nav> </header> <main class="main"> <h2>Index</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p> <footer class="footer"> <p>© 2020 - All rights reserved</p> <p><a href="${SOCIAL_LINK_1}">${SOCIAL_NAME_1}</a> | <a href="${SOCIAL_LINK_2}">${SOCIAL_NAME_2}</a> | <a href="${SOCIAL_LINK_3}">${SOCIAL_NAME_3}</a> </p> </footer> </main> </body> </html> EOF # about.html cat <<EOF > "${ABOUTHTML}" <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>About | ${SITE_NAME}</title> <meta name="robots" content="index, follow" /> <meta name="googlebot" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1" /> <meta name="bingbot" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1" /> <meta name="keywords" content="about, ${SITE_NAME}"/> <link rel="canonical" href="${SITE_LINK}/${MENU_LINK_2}" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" type="text/css" href="css/normalize.css"> <link rel="stylesheet" type="text/css" href="css/style.css"> </head> <body> <header class="header"> <h1 class="logo">${SITE_NAME}</h1> <nav class="menu"> <ul class="menu_ul"> <li><a href="${MENU_LINK_1}">${MENU_NAME_1}</a></li> <li><a class="active" href="${MENU_LINK_2}">${MENU_NAME_2}</a></li> <li><a href="${MENU_LINK_3}">${MENU_NAME_3}</a></li> <li><a href="${MENU_LINK_4}">${MENU_NAME_4}</a></li> <li><a href="${MENU_LINK_5}">${MENU_NAME_5}</a></li> </ul> </nav> </header> <main class="main"> <h2>About</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p> <footer class="footer"> <p>© 2020 - All rights reserved</p> <p><a href="${SOCIAL_LINK_1}">${SOCIAL_NAME_1}</a> | <a href="${SOCIAL_LINK_2}">${SOCIAL_NAME_2}</a> | <a href="${SOCIAL_LINK_3}">${SOCIAL_NAME_3}</a> </p> </footer> </main> </body> </html> EOF # blog.html cat <<EOF > "${BLOGHTML}" <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Blog | ${SITE_NAME}</title> <meta name="robots" content="index, follow" /> <meta name="googlebot" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1" /> <meta name="bingbot" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1" /> <meta name="keywords" content="blog, ${SITE_NAME}"/> <link rel="canonical" href="${SITE_LINK}/${MENU_LINK_3}" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" type="text/css" href="css/normalize.css"> <link rel="stylesheet" type="text/css" href="css/style.css"> </head> <body> <header class="header"> <h1 class="logo">${SITE_NAME}</h1> <nav class="menu"> <ul class="menu_ul"> <li><a href="${MENU_LINK_1}">${MENU_NAME_1}</a></li> <li><a href="${MENU_LINK_2}">${MENU_NAME_2}</a></li> <li><a class="active" href="${MENU_LINK_3}">${MENU_NAME_3}</a></li> <li><a href="${MENU_LINK_4}">${MENU_NAME_4}</a></li> <li><a href="${MENU_LINK_5}">${MENU_NAME_5}</a></li> </ul> </nav> </header> <main class="main"> <h2>Blog</h2> <ul class="posts"> </ul> <footer class="footer"> <p>© 2020 - All rights reserved</p> <p><a href="${SOCIAL_LINK_1}">${SOCIAL_NAME_1}</a> | <a href="${SOCIAL_LINK_2}">${SOCIAL_NAME_2}</a> | <a href="${SOCIAL_LINK_3}">${SOCIAL_NAME_3}</a> </p> </footer> </main> </body> </html> EOF # downloads.html cat <<EOF > "${DOWNLOADSHTML}" <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Downloads | ${SITE_NAME}</title> <meta name="robots" content="index, follow" /> <meta name="googlebot" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1" /> <meta name="bingbot" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1" /> <meta name="keywords" content="downloads, ${SITE_NAME}"/> <link rel="canonical" href="${SITE_LINK}/${MENU_LINK_4}" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" type="text/css" href="css/normalize.css"> <link rel="stylesheet" type="text/css" href="css/style.css"> </head> <body> <header class="header"> <h1 class="logo">${SITE_NAME}</h1> <nav class="menu"> <ul class="menu_ul"> <li><a href="${MENU_LINK_1}">${MENU_NAME_1}</a></li> <li><a href="${MENU_LINK_2}">${MENU_NAME_2}</a></li> <li><a href="${MENU_LINK_3}">${MENU_NAME_3}</a></li> <li><a class="active" href="${MENU_LINK_4}">${MENU_NAME_4}</a></li> <li><a href="${MENU_LINK_5}">${MENU_NAME_5}</a></li> </ul> </nav> </header> <main class="main"> <h2>Downloads</h2> <footer class="footer"> <p>© 2020 - All rights reserved</p> <p><a href="${SOCIAL_LINK_1}">${SOCIAL_NAME_1}</a> | <a href="${SOCIAL_LINK_2}">${SOCIAL_NAME_2}</a> | <a href="${SOCIAL_LINK_3}">${SOCIAL_NAME_3}</a> </p> </footer> </main> </body> </html> EOF echo "html files successfully created!" exit 0 else sleep 0 fi # check if blog.html file exists to create the post if [[ -e "${BLOGHTML}" ]] ; then cat <<EOF > "${post_dir}/${final_date}/${post_title_lower// /-}.html" <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Blog | ${post_title}</title> <meta name="robots" content="index, follow" /> <meta name="googlebot" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1" /> <meta name="bingbot" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1" /> <meta name="keywords" content="${keywords}, ${SITE_NAME}"/> <link rel="canonical" href="${SITE_LINK}/post/${post_session_upper// /-}/${final_date}/${post_title_lower// /-}.html" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" type="text/css" href="../../../../../css/normalize.css"> <link rel="stylesheet" type="text/css" href="../../../../../css/style.css"> </head> <body> <header class="header"> <h1 class="logo">${SITE_NAME}</h1> <nav class="menu"> <ul class="menu_ul"> <li><a href="../../../../../${MENU_LINK_1}">${MENU_NAME_1}</a></li> <li><a href="../../../../../${MENU_LINK_2}">${MENU_NAME_2}</a></li> <li><a class="active" href="../../../../../${MENU_LINK_3}">${MENU_NAME_3}</a></li> <li><a href="../../../../../${MENU_LINK_4}">${MENU_NAME_4}</a></li> <li><a href="${MENU_LINK_5}">${MENU_NAME_5}</a></li> </ul> </nav> </header> <main class="main"> <article> <header> <h2>${post_title}</h2> </header> <p>TEXT HERE</p> <footer> <p>TAGS: ${keywords} </p> </footer> </article> <footer class="footer"> <p>© 2020 - All rights reserved</p> <p><a href="${SOCIAL_LINK_1}">${SOCIAL_NAME_1}</a> | <a href="${SOCIAL_LINK_2}">${SOCIAL_NAME_2}</a> | <a href="${SOCIAL_LINK_3}">${SOCIAL_NAME_3}</a> </p> </footer> </main> </body> </html> EOF else echo "ERROR: blog.html Does not exist." fi } # Create directories and execute fuction BASE_HTML NEW(){ if [[ -d "${DIR_SITE}" ]]; then echo "Files already exist!" exit 0 else echo "Creating the necessary files and folders" mkdir -v "${DIR_SITE}" ; \ mkdir -v "${DIR_POST}" ; \ mkdir -v "${DIR_CSS}" ; \ mkdir -v "${DIR_IMG}" ; \ mkdir -v "${DIR_FILES}" ; \ touch "${STYLE_CSS}" ; \ touch "${NORMALIZE_CSS}" ; \ BASE_HTML ; \ exit 0 fi } ADD_SESSION(){ CHECK_FILES read -ep "Session name: " new_session # check if variable is null if [[ -z "${new_session}" ]] ; then echo "ERROR: name not specified" exit 1 else sleep 0 fi # check if variable has special characters if [[ "${new_session}" =~ ^[0-9A-Za-z\ ]+$ ]] && [[ "${new_session}" != *['!'@#\$%^ÀÈÌÒÙùòìèàÝÚÓÍÉÁýúóíéáÛÔÎÊÂûôîêâÕÑÃõñãŸÜÖÏËÄÿüöïëäÇç\&*()_+]* ]] ; then sleep 0 else echo "ERROR: has special characters" exit 1 fi # variables local new_session_upper="${new_session^^}" local new_session_lower="${new_session,,}" local pattern_ul='<ul class="posts">' # check if directory already exists if [[ ! -d "${DIR_POST}/${new_session_upper// /-}" ]]; then mkdir -v "${DIR_POST}/${new_session_upper// /-}" else echo "ERROR: directory already exists" exit 1 fi # add to html tags for list creation below the <ul class="posts"> tag sed -i '/'"${pattern_ul}"'/a <\!-- SESSION:'"${new_session_upper// /-}"' -->' ${BLOGHTML} sed -i '/<\!-- SESSION:'"${new_session_upper// /-}"' -->/a <\!-- FINAL SESSION:'"${new_session_upper// /-}"' -->' ${BLOGHTML} sed -i 's/<\!-- SESSION:'"${new_session_upper// /-}"' -->/<\!-- SESSION:'"${new_session_upper// /-}"' -->\n<li class="'"${new_session_lower// /-}"'">\n<h3>'"${new_session_upper}"'<\/h3>\n<ul class="'"${new_session_lower// /-}"'">\n<\/ul>/' ${BLOGHTML} } DEL_SESSION(){ CHECK_FILES read -ep "Session name: " session_name # variables local session_name_upper="${session_name^^}" local session_name_lower="${session_name,,}" # check if session exists if grep -qow '<ul class="'"${session_name_lower// /-}"'">' ${BLOGHTML} ; then sleep 0 else echo "ERROR: Session does not exist!." exit 1 fi # asks if you want to delete session read -p "Delete ${session_name_upper} session??? [y/n]: " question if [ "${question}" != "${question#[Yy]}" ] ;then echo "Deleting ${session_name_upper}" sed -i '/<\!-- SESSION:'"${session_name_upper// /-}"' -->/,/<\!-- FINAL SESSION:'"${session_name_upper// /-}"' -->/d' ${BLOGHTML} else echo "preserved "${session_name}".html session" exit 0 fi # asks if you want to delete session directory read -p "Delete directory session ${session_name_upper// /-}??? [y/n]: " question2 read -ep "CAUTION: this will delete all html posts contained in the directory, are you sure you want to continue? [y/n]: " question2 if [[ "${question2}" != "${question2#[Yy]}" ]] ; then echo "Deleting directory ${session_name_upper// /-}" rm -rv ${DIR_POST}/${session_name_upper// /-} else echo "Directory "${session_name_upper// /-}" preserved" exit 0 fi } ADD_POST(){ CHECK_FILES read -ep "Add to session: " post_session # variables local post_session_upper="${post_session^^}" local post_session_lower="${post_session,,}" # check if session exists if grep -qow '<ul class="'"${post_session_lower// /-}"'">' ${BLOGHTML} ; then sleep 0 else echo "ERROR: Session does not exist!." exit 1 fi # post dir local post_dir="${DIR_POST}/${post_session_upper// /-}" # Date default ISO-8601 # Year local year=$(date +%Y) if [[ ! -d "${post_dir}/${year}" ]]; then mkdir -v "${post_dir}/${year}" else sleep 0 fi # Month local month=$(date +%m) if [[ ! -d "${post_dir}/${year}/${month}" ]]; then mkdir -v "${post_dir}/${year}/${month}" else sleep 0 fi # Day local day=$(date +%d) if [[ ! -d "${post_dir}/${year}/${month}/${day}" ]]; then mkdir -v "${post_dir}/${year}/${month}/${day}" else sleep 0 fi # Final date post. local final_date="$(date +%Y/%m/%d)" local final_date_hour="$(date +"%Y-%m-%d %R:%S" | xargs)" read -ep "Post title: " post_title local post_title_upper="${post_title^^}" local post_title_lower="${post_title,,}" # check if variable is null if [[ -z "${post_title}" ]] ; then echo "ERROR: no name specified" exit 1 else sleep 0 fi # check if variable has special characters if [[ "${post_title}" =~ ^[0-9A-Za-z\ ]+$ ]] && [[ "${post_title}" != *['!'@#\$%^ÀÈÌÒÙùòìèàÝÚÓÍÉÁýúóíéáÛÔÎÊÂûôîêâÕÑÃõñãŸÜÖÏËÄÿüöïëäÇç\&*()_+]* ]] ; then sleep 0 else echo "ERROR: has special characters" exit 1 fi read -p "Keywords: " keywords # checks if post already exists if [[ -e "${post_dir}/${final_date}/${post_title_lower// /-}".html ]]; then echo "ERROR: "${post_dir}/${final_date}/${post_title_lower// /-}".html already exists!." exit 1 else sleep 0 fi # add post link to blog.html sed -i "/<ul class=\"${post_session_lower// /-}\">/a <li><article><a href=\"post\/${post_session_upper// /-}/${final_date}/${post_title_lower// /-}.html\" title=\"${post_title}\">${post_title} | <time datetime=\"${final_date_hour}\">${final_date}</time></a></article></li> " ${BLOGHTML} # executes BASE_HTML fuction BASE_HTML # check if the directories and html were created correctly if [[ -e "${post_dir}/${final_date}/${post_title_lower// /-}".html ]]; then echo "POST "${post_dir}/${final_date}/${post_title_lower// /-}".html CREATED SUCCESSFULLY!" else echo "ERROR: "${post_dir}/${final_date}/${post_title_lower// /-}".html NOT CREATED!" exit 1 fi "${EDITOR}" "${post_dir}/${final_date}/${post_title_lower// /-}".html } DEL_POST(){ CHECK_FILES read -ep "Post session: " post_session # variables local post_session_upper="${post_session^^}" local post_session_lower="${post_session,,}" # check if session exists if grep -qow '<ul class="'"${post_session_lower// /-}"'">' ${BLOGHTML} ; then sleep 0 else echo "ERROR: Session does not exist!." exit 1 fi # Year read -p "Year: " year_post # check if variable is null if [[ -z "${year_post}" ]] ; then echo "ERROR: name not specified" exit 1 else sleep 0 fi # checks if the variable has only four digits if [[ "${year_post}" = ?(+|-)+([0-9]) ]] && [[ "${#year_post}" -eq 4 ]] ; then sleep 0 else echo "ERROR: value must be numeric and only have four digits" exit 1 fi # Month read -ep "Month: " month_post # check if variable is null if [[ -z "${month_post}" ]] ; then echo "ERROR: name not specified" exit 1 else sleep 0 fi # checks if the variable has only two digits if [[ "${month_post}" = ?(+|-)+([0-9]) ]] && [[ "${#month_post}" -eq 2 ]] ; then sleep 0 else echo "ERROR: value must be numeric and only have two digits" exit 1 fi # Day read -ep "Day: " day_post # check if variable is null if [[ -z "${day_post}" ]] ; then echo "ERROR: name not specified" exit 1 else sleep 0 fi read -ep "Post title: " post_title # variables local post_title_upper="${post_title^^}" local post_title_lower="${post_title,,}" # check if variable is null if [[ -z "${post_title}" ]] ; then echo "ERROR: name not specified" exit 1 else sleep 0 fi # check if variable has special characters if [[ "${post_title}" =~ ^[0-9A-Za-z\ ]+$ ]] && [[ "${new_session}" != *['!'@#\$%^ÀÈÌÒÙùòìèàÝÚÓÍÉÁýúóíéáÛÔÎÊÂûôîêâÕÑÃõñãŸÜÖÏËÄÿüöïëäÇç\&*()_+]* ]] ; then sleep 0 else echo "ERROR: has special characters" exit 1 fi # Checks if html file exists if [[ -e "${DIR_POST}/${post_session_upper// /-}/${year_post}/${month_post}/${day_post}/${post_title_lower// /-}.html" ]] ; then sleep 0 else echo "ERROR: ${post_title_lower// /-}.html file does not exist!." exit 1 fi # checks if the variable has only two digits if [[ "${day_post}" = ?(+|-)+([0-9]) ]] && [[ "${#day_post}" -eq 2 ]] ; then sleep 0 else echo "ERROR: value must be numeric and only have two digits" exit 1 fi # asks if you want to delete the html file read -p "Delete "${post_title_lower// /-}".html file??? [y/n]: " question if [ "${question}" != "${question#[Yy]}" ] ;then echo "Deleting ${post_title_lower// /-}" sed -i '/<li><article><a href="post\/'"${post_session_upper// /-}"'\/'"${year_post}"'\/'"${month_post}"'\/'"${day_post}"'\/'"${post_title_lower// /-}"'.html" title=\"'"${post_title_lower}"'\">/d' ${BLOGHTML} rm -vr "${DIR_POST}/${post_session_upper// /-}/${year_post}/${month_post}/${day_post}/${post_title_lower// /-}.html" else echo "preserved "${post_title_lower// /-}".html file" exit 0 fi # delete the day directory if empty if [ -z "$(ls -A ${DIR_POST}/${post_session_upper// /-}/${year_post}/${month_post}/${day_post}/)" ]; then rmdir -v "${DIR_POST}/${post_session_upper// /-}/${year_post}/${month_post}/${day_post}/" else sleep 0 fi # delete the month directory if empty if [ -z "$(ls -A ${DIR_POST}/${post_session_upper// /-}/${year_post}/${month_post}/)" ]; then rmdir -v "${DIR_POST}/${post_session_upper// /-}/${year_post}/${month_post}/" else sleep 0 fi # delete the year directory if empty if [ -z "$(ls -A ${DIR_POST}/${post_session_upper// /-}/${year_post}/)" ]; then rmdir -v "${DIR_POST}/${post_session_upper// /-}/${year_post}/" else sleep 0 fi } BROWSER(){ CHECK_FILES x-www-browser "${INDEXHTML}" } HELP() { cat <<EOF bashblog v1.0 This script creates a base for a website in html5, configure the variables in the bashblog.sh file in double quotes, do not change the paths, the html files are created through the base_html fuction. USAGE: ./bashblog [OPTIONS] Arguments: -n Create necessary directories and folders -s Adds new session -ds Delete session -p Adds new post to session -dp Delete post -b Opens website in browser EOF } case $1 in "-n") NEW ; ;; "-s") ADD_SESSION ; ;; "-ds") DEL_SESSION ; ;; "-p") ADD_POST ; ;; "-dp") DEL_POST ; ;; "-b") BROWSER ; ;; *) HELP ; exit 1 ; ;; esac
POSTFIX AUTOMÁTICO COM MYSQL E IPTABLES - LÊ O BANCO E EXIBE OS DADOS
Script para modificar Encoding de UTF-8 para ISO-8859-1
Script de compilação automática do GCC-5.3.0 para Debian/Ubuntu de 32 bits
Instalar o Java diretamente do site oficial
Título: Descobrindo o IP externo da VPN no Linux
Armazenando a senha de sua carteira Bitcoin de forma segura no Linux
Enviar mensagem ao usuário trabalhando com as opções do php.ini
Encontre seus arquivos facilmente com o Drill
Mouse Logitech MX Ergo Advanced Wireless Trackball no Linux
Compartilhamento de Rede com samba em modo Público/Anônimo de forma simples, rápido e fácil
Cups: Mapear/listar todas as impressoras de outro Servidor CUPS de forma rápida e fácil
O que você está ouvindo agora? [2] (169)
Alternar as janelas clicando na barra de tarefas (8)
Erro no Visual Studio Code impede que ele execute qualquer código em c... (0)
qual tipo de interface linux para processador do tipo apu (9)