Este blog es de un puertorriqueño con suerte que obtuvo un trabajo en algo que nunca habia hecho. Aquí encontrarás guías técnicas de las tareas de Linux Administration, Shell Scripting, MySQL y Oracle que me han asignado y he tenido que aprender por cuenta propia.
Hoy tuve que hacer un script para generar un reporte que contenga información del mes pasado completo. Para encontrar el primer día del mes pasado utlizamos este comando:
Para mi primer proyecto de Arduino y Android decidí controlar mi aire acondicionado con receptor infrarrojo con una aplicación de android en mi celular desde cualquier lugar que me encuentre que tenga acceso a internet. Video del resultado final
Este proceso lo realicé en un ambiente Windows pero es lo mismo para Linux. Aquí les explicaré como lo logré.
Prerequisitos:
- Aire Acondicionado
- Control remoto del aire acondicionado (Tiene que funcionar para poder decodificar el IR)
Primero añadimos (unzip) las librerias que descargamos la carpeta de libraries donde se instaló el SDK de Arduino.
X:\...\arduino-1.0.4\libraries
Luego nos aseguramos que el Arduino este conectado a la computadora y que Windows haya instalado bien el driver.
Ahora tenemos que decirle al SDK que board y que puerto de comunicación utilizaremos.
Tools > Board > Arduino Mega 2560 or Mega ADK
Tools > Serial Port > (El puerto donde se haya detectado tu arduino)
Ahora tenemos que conectar el IR Receiver al Arduino de la siguiente manera:
Pin 1 va al pin 19 del Arduino.
Pin 2 va al pin de Ground.
Pin 3 va al pin de 5V.
Ilustración:
Luego copiamos este sketch en el Arduino SDK.
/*
* IRremote: IRrecvDump - dump details of IR codes with IRrecv
* An IR detector/demodulator must be connected to the input RECV_PIN.
* Version 0.1 July, 2009
* Copyright 2009 Ken Shirriff
* http://arcfn.com
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
*/
#include <IRremote.h>
int RECV_PIN = 19;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
}
// Dumps out the decode_results structure.
// Call this after IRrecv::decode()
// void * to work around compiler issue
//void dump(void *v) {
// decode_results *results = (decode_results *)v
void dump(decode_results *results) {
int count = results->rawlen;
if (results->decode_type == UNKNOWN) {
Serial.print("Unknown encoding: ");
}
else if (results->decode_type == NEC) {
Serial.print("Decoded NEC: ");
}
else if (results->decode_type == SONY) {
Serial.print("Decoded SONY: ");
}
else if (results->decode_type == RC5) {
Serial.print("Decoded RC5: ");
}
else if (results->decode_type == RC6) {
Serial.print("Decoded RC6: ");
}
else if (results->decode_type == PANASONIC) {
Serial.print("Decoded PANASONIC - Address: ");
Serial.print(results->panasonicAddress,HEX);
Serial.print(" Value: ");
}
else if (results->decode_type == JVC) {
Serial.print("Decoded JVC: ");
}
Serial.print(results->value, HEX);
Serial.print(" (");
Serial.print(results->bits, DEC);
Serial.println(" bits)");
Serial.print("Raw (");
Serial.print(count, DEC);
Serial.print("): ");
for (int i = 0; i < count; i++) {
if ((i % 2) == 1) {
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
}
else {
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
}
Serial.print(" ");
}
Serial.println("");
}
void loop() {
if (irrecv.decode(&results)) {
Serial.println(results.value, HEX);
dump(&results);
irrecv.resume(); // Receive the next value
}
}
Quedará algo así:
Oprimimos (verify) para que se valide/compile el código y luego (upload) para que suba a nuestro Arduino.
En este momento debes ir a al menú de Tools y abrir el Serial Monitor. Luego de que lo abras, con el control remoto del aire acondicionado apunta al IR Receiver y aprietas los botones uno a uno. Obtendrás algo así:
En este caso el control de mi AC resultó ser uno marca NEC con los siguientes codigos:
Decoded NEC: 80FF48B7 (32 bits) - AC ON
Decoded NEC: 80FFC837 (32 bits) - TEMP UP
Decoded NEC: 80FF58A7 (32 bits) - TEMP DOWN
Decoded NEC: 80FFD827 (32 bits) - TIMER
Ya tenemos una parte completada. Ahora hacemos otro sketch, esta ves para implementar el webserver que nos va a ayudar a ejecutar los comandos en el arduino. Para hacer esto utilicé y modifiqué el ejemplo de Web_Demo de la librería de Webduino. Aqui debes asegurarte de definir las siguientes cosas: -Tengas el EthernetShield ya instalado en tu MEGA 2560. -Debes definir el MAC Address de tu Ethernet Shield y su IP. -Debes definir el puerto donde el webserver estará corriendo. -Debes cambiar los comandos infrarrojos por los que obtuviste. -El IR LED debe estar en el arduino con el ánodo (negativo) en GRD y el cátodo (patita mas larga, positivo) en el pin #9.
* Web_Demo.pde -- sample code for Webduino server library */
/*
* To use this demo, enter one of the following USLs into your browser.
* Replace "host" with the IP address assigned to the Arduino.
*
* http://host/
* http://host/acOn
*
* This URL turns on the Air Conditioner
*
*/
#include "SPI.h"
#include "Ethernet.h"
#include "WebServer.h"
#include <IRremote.h>
// no-cost stream operator as described at
// http://sundial.org/arduino/?page_id=119
template<class T>
inline Print &operator <<(Print &obj, T arg)
{ obj.print(arg); return obj; }
//IR Variable declaration
IRsend irsend;
// CHANGE THIS TO YOUR OWN UNIQUE VALUE
static uint8_t mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
// CHANGE THIS TO MATCH YOUR HOST NETWORK
static uint8_t ip[] = { 192, 168, 1, X };
#define PREFIX ""
WebServer webserver(PREFIX, 80 ); //ASSIGN PORT HERE
// commands are functions that get called by the webserver framework
// they send the IR Code to the AC
void acOn(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
if (type == WebServer::POST)
{
server.httpFail();
return;
}
//server.httpSuccess(false, "application/acOn");
server.httpSuccess();
//Replace for your IR Code here.
irsend.sendNEC(0x80FF48B7, 32); //irsend.send(IRTYPE)(0x(IRCODE), (BITS));
delay(40);
}
void tempUp(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
if (type == WebServer::POST)
{
server.httpFail();
return;
}
server.httpSuccess();
//Replace for your IR Code here.
irsend.sendNEC(0x80FFC8A7, 32); //irsend.send(COMPANYIR)(0x(IRCODE), (BITS));
delay(40);
}
void tempDown(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
if (type == WebServer::POST)
{
server.httpFail();
return;
}
server.httpSuccess();
//Replace for your IR Code here.
irsend.sendNEC(0x80FF5837, 32); //
delay(40);
}
void timer(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
if (type == WebServer::POST)
{
server.httpFail();
return;
}
server.httpSuccess();
//Replace for your IR Code here.
irsend.sendNEC(0x80FFD827, 32); //
delay(40);
}
void setup()
{
Ethernet.begin(mac, ip);
webserver.begin();
//Rename the commands to your liking
webserver.addCommand("acon", &acOn);
webserver.addCommand("tempup", &tempUp);
webserver.addCommand("tempdown", &tempDown);
webserver.addCommand("timer", &timer);
}
void loop()
{
// process incoming connections one at a time forever
webserver.processConnection();
// if you wanted to do other work based on a connecton, it would go here
}
Oprimimos (verify) para que se valide/compile el código y luego (upload) para que suba a nuestro Arduino. En este momento ya puedes manejar tu aire acondicionado desde el web browser de alguna computadora conectada a tu misma red. Con poner (IP simulado) http://192.168.1.20/acon el aire acondicionado debe prender. Ahora esto es opcional y bajo su reponsabilidad por las posibles consecuencias de seguridad que pueda traer. Para poder manejar el arduino de cualquier lugar en el internet necesitaremos hacer una regla de "Port Forward" en nuestro router. La misma debe contener el IP del arduino y el puerto escogido para el webserver. Les recomiendo que utilicen un puerto que no sea el 80. Luego de que hagan esa regla van a poder acceder el webserver en el arduino desde el internet y no limitado a su network. La aplicación de android no es realmente necesaria pues ya puedes controlar el aire desde tu web browser desde el internet. Pero es mas interesante (y se ve mas cool) tener un app para esto. Soy un beginner programando en android asi que muchas de las cosas que hice lo mas probable se pueden hacer de una manera mas efectiva. Aquí les dejo el projecto de la aplicación de Android: Descarga
Modifiquenla de acuerdo a su setup y ya! Cualquier pregunta dejenme saber!
Hoy tuve la necesidad de automatizar reportes que se generan utilizando información de varias bases de datos Oracle. El Oracle Instant Client nos permite accesar y manejar bases de datos utilizando sqlplus sin la necesidad de hacer una instalacion completa. Aquí verás como hacer esta instalación. 1. Primero necesitamos bajar el Instant Client y sqlplus de aqui.
4. Ahora creamos el usuario y le asignamos un password: **Nota: Si tu sistema es 32 bits elimina el numero 64 de todos los comandos que sometamos de este paso en adelante.
5. Modificamos el profile del usuario oracle (añade las lineas en negro):
vim ~oracle/.bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export LD_LIBRARY_PATH=/usr/lib/oracle/11.2/client64/lib
export TNS_ADMIN=/usr/lib/oracle/11.2/client64
export ORACLE_HOME=/usr/lib/oracle/11.2/client64
PATH=$ORACLE_HOME/bin:$PATH
export PATH
6. Creamos el archivo tnsnames.ora que es donde se definen las conexiones de las bases de datos:
$ vim /usr/lib/oracle/11.2/client/tnsnames.ora
Recuerda: Las entradas en este archivo deben tener este formato:
Entras al servidor con el usuario oracle e intentamos conexion a una base de datos con el siguiente comando:
$ sqlplus user/pass@DB
SQL*Plus: Release 11.2.0.3.0 Production on Fri Jan 25 14:30:01 2013
Copyright (c) 1982, 2011, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL>
**Nota: Para tener la misma funcionalidad con el usuario root solo tienes que repetir el paso #5 en su .bash_profile.
Ya tenemos el Instant Client 11g de Oracle instalado y conectado a una base de datos!
Heredé un servidor SunOS que tiene ya una instalación de Oracle a la cual quiero conectarme a través de command line usando 'sqlplus'. Cuando utilizé el comando me daba este error:
$ sqlplus
sqlplus: not found
¿La causa? La variable de $ORACLE_HOME no estaba configurada. Aquí te voy a decir como solucionar ese problema.
1) Primero verificamos que tiene la variable de $ORACLE_HOME y confirmamos que esta vacía. De no estarlo entonces salta al paso 3.
$ $ORACLE_HOME
$
2) Ahora necesitamos saber donde esta la instalación de Oracle. En mi caso estaba en /home/app/oracle/product/10.2.0. **Nota: El ORACLE_HOME es un nivel antes de donde se encuentra el archivo llamado bin. La parte en negro es el ORACLE_HOME:/home/app/oracle/product/10.2.0/bin
Le asignamos el valor a la variable $ORACLE_HOME y le damos export.
Ya podemos intentar conectarnos con el comando 'sqlplus'
$ sqlplus
SQL*Plus: Release 10.2.0.4.0 - Production on Thu Jan 17 16:15:39 2013
Copyright (c) 1982, 2007, Oracle. All Rights Reserved.
Enter user-name:
Este script es sencillo pero muy útil. Para ahorrar espacio en el servidor necesito borrar todos los archivos de hace más de 3 dias en diferentes directorios, diariamente. Este script me permite hacer esto automáticamente.
En la variable $PATH ponemos todos los directorios que deseamos limpiar separados por un espacio. Luego el comando find se encargara de ir directorio por directorio listando (-ls) todos los archivos mayores de tres dias (-mtime +3). El resultado de ese ls (los nombres de nuestros archivos) serán eliminados por -exec rm{}. Puedes modificar el tiempo de acuerdo a tu necesidad, por ejemplo -mtime +0 eliminaria todos los archivos que no sean del dia corriente.
"Si tienes que hacer una tarea más de una vez, haz un script".
Aqui verás un ejemplo de Shell Script que envía por FTP todos los archivos del día de hoy encontrados en una carpeta en específico.
#!/bin/sh
#IP donde te quieres conectar
HOST='192.168.0.10'
#Usuario de conexion
USER='ftpuser'
#Contrasena del usuario
PASSWD='ftppass'
#Path donde quieres buscar los archivos
PATH='/home/ftpuser/reports'
#Path donde los depositaras
DESTINATION='/destinationserver/destinationfolder'
#Busca todos los archivos en $PATH donde la fecha de modificacion (-ctime) sea# 0 = hoy. Por cada archivo que encuentres (while read LINE).
#Conectate al host y deposita el archivo (put $LINE)
find $PATH -type f -ctime 0 | while read LINE
do
ftp -n $HOST <<END_SCRIPT
quote USER $USER
quote PASS $PASSWD
cd $DESTINATION
put $LINE
quit
END_SCRIPT
done
Recuerda ajustar los niveles de seguridad del script de acuerdo a tu necesidad y ponerlo en tu crontab.
Quizás en algún momento necesites que algún extraño entre a tu servidor a recoger unos archivos. Por razones de seguridad no quieres que ese extraño ejecute comandos ni que acceda archivos que no le competen. Por eso hoy te voy a mostrar como crear un usuario que tenga acceso a FTP *solamente* en SunOS .
1. Creamos el usuario.
useradd -m ftpuser
2. Le asignamos un password
passwd ftppassword
3. Necesitamos asignarle un shell al usuario que no le permita ejecutar comandos pero si que le permita hacer login. Por lo que le vamos a asignar /bin/false
usermod -s /bin/false ftpuser
4. Hay que asegurarnos que el shell que le asignamos se encuentre en el grupo de los shells autorizados a hacer login. Así que corremos el próximo comando, editamos el archivo /etc/shells y añadimos /bin/false (si es que no se encuentra).
vi /etc/shells
/bin/bash
/bin/csh
/bin/hash
/bin/jsh
/bin/ksh
/bin/pfcsh
/bin/pfksh
/bin/pfsh
/bin/remsh
/bin/rksh
/bin/rsh
/bin/sh
/bin/ssh
/bin/tcsh
/bin/zsh
/bin/ftpaccess
/sbin/sh
# add this line
/bin/false
*Nota: Si el archivo de /etc/shells no existe puedes crearlo pero tienes que asegurarte que incluyas todos los shells en tu sistema pues los shells que no estén aquí no podrán hacer login al sistema. 5. Vamos a restringir el usuario a su home folder mediante este comando:
ftpconfig -d /home/ftpuser
6. Tenemos que editar el archivo de ftpaccess para decirle que usuario vamos a estar limitando.
vi /etc/ftpd/ftpaccess
Obtendrás esto:
# ident "@(#)ftpaccess 1.1 01/06/26 SMI"
#
# FTP server configuration file, see ftpaccess(4).
#
class realusers real *
class guestusers guest *
class anonusers anonymous *
loginfails 3
passwd-check trivial warn
private no
keepalive yes
shutdown /etc/ftpd/shutdown.msg
# email user@hostname
guestuser ftpuser
# timeout idle 300
banner /etc/ftpd/banner.msg
greeting brief
message /etc/ftpd/welcome.msg login
message .message cwd=*
readme README* login
readme README* cwd=*
chmod no anonymous
delete no anonymous
overwrite no anonymous
rename no anonymous
umask no anonymous
compress yes realusers guestusers anonusers
tar yes realusers guestusers anonusers
...
Hay que asegurarnos que la línea de "class guestusers guest *" se encuentre en el archivo, que la línea de "guestuser username" no este comentada y que en vez de username diga el nombre del usuario que queremos limitar "guestuser ftpuser". Salvamos el archivo.
7. Ahora corremos este comando para permitir el uso del file ftpaccess.
in.ftpd -a
Ya terminamos. Ahora solo resta hacer dos pruebas.
Prueba 1: Conexión mediante FTP para asegurarnos que no pueda acceder nada mas que su Home Folder.
ftp 1.1.1.1.1
Connected to 1.1.1.1.1
Name (1.1.1.1.1:root): ftpuser
331 Password required for ftpuser.
Password:
230 User ftpuser logged in. Access restrictions apply.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> pwd
257 "/" is current directory.
ftp> cd ..
250 CWD command successful.
ftp> pwd
257 "/" is current directory.
ftp>
Podemos ver que mi directorio actual dice "/" en vez de "/home/ftpuser". Prueba 2: Conexión mediante Putty.
Intente conectarse al servidor mediante Putty con las credenciales del usuario de ftp. Al poner las credenciales Putty se cerrará evitando que el usuario pueda ejecutar comandos directo en el command line. Esto es gracias al shell /bin/false. Terminamos!