El Software y el conocimiento debe ser Libre
Posts tagged Shell Script
shell script – Baccarat game
Dec 1st
Para el que se quiera entretener en mejorar el script del juego de Baccarat, aquí lo tenéis.
#!/bin/sh
# Baccarat game, shell script written
function initializeDeck
{
card=1
while [ $card -lt 53 ]
do
deck[$card]=$card
card=$(( $card + 1 ))
done
player[1]=-1; player[2]=-1; player[3]=-1; player[4]=-1; player[5]=-1
banker[1]=-1; banker[2]=-1; banker[3]=-1; banker[4]=-1; banker[5]=-1
}
function pickCard
{
local errcount randomcard
threshold=10 # max guesses for a card before we fall through
errcount=0
while [ $errcount -lt $threshold ]
do
randomcard=$(( ( $RANDOM % 52 ) + 1 ))
errcount=$(( $errcount + 1 ))
if [ ${deck[$randomcard]} -ne 0 ] ; then
picked=${deck[$randomcard]}
deck[$picked]=0 # picked, remove it
# echo randomly picked $picked
return $picked
fi
done
# If we get here, we've been uanble to randomly pick a card
# so now we'll just step up until we find an available card
randomcard=1
while [ ${deck[$randomcard]} -eq 0 ]
do
randomcard=$(( $randomcard + 1 ))
done
picked=$randomcard
deck[$picked]=0 # picked, remove it
# echo fell through, picked $picked
return $picked
}
function shuffleDeck
{
count=1
while [ $count -le 52 ]
do
pickCard
newdeck[$count]=$picked
# echo " .. pickCard returned $picked"
count=$(( $count + 1 ))
done
}
function showCard
{
card=$1
if [ $card -lt 1 -o $card -gt 52 ] ; then
echo "Bad card value: $card"
exit 1
fi
suite="$(( ( ( $card - 1) / 13 ) + 1))"
rank="$(( $card % 13))"
case $suite in
1 ) suite="Hearts" ;;
2 ) suite="Clubs" ;;
3 ) suite="Spades" ;;
4 ) suite="Diamonds" ;;
* ) echo "Bad suite value: $suite"; exit 1
esac
case $rank in
0 ) rank="King" ;;
1 ) rank="Ace" ;;
11) rank="Jack" ;;
12) rank="Queen" ;;
esac
cardname="$rank of $suite"
}
function handValue
{
# feed this as many cards as are in the hand. This uses weird Baccarat
# hand value scoring: 1-9 are their own point values, 10,J,Q,K are 0
handvalue=0 # initialize
for cardvalue
do
if [ $cardvalue -ge 0 ] ; then
rankvalue=$(( $cardvalue % 13 ))
case $rankvalue in
0|11|12 ) rankvalue=0 ;;
1 ) rankvalue=11 ;;
esac
handvalue=$(( $handvalue + $rankvalue ))
fi
done
handvalue=$(( $handvalue % 10 ))
}
function dealBanker
{
# Banker draws a card
banker[$nextbankercard]=${newdeck[$nextcard]}
handValue ${banker[1]} ${banker[2]} ${banker[3]}
bankerhandvalue=$handvalue
echo -n "Banker takes a card: "
showCard ${banker[$nextbankercard]}
echo "$cardname (hand value = $bankerhandvalue)"
}
function showResult
{
# This determines who wins: "Banker", "Player" or "Tie".
if [ $bankerhandvalue -gt $playerhandvalue ] ; then
echo "Banker wins"
result=1
elif [ $bankerhandvalue -lt $playerhandvalue ] ; then
echo "Player wins"
result=2
else
echo "Tie"
result=3
fi
}
#################################################################
#### The main code block ....
initializeDeck
shuffleDeck
cat << EOF
Welcome to Baccarat. You can choose to either stake the player or banker
to win this game. Remember, face cards are worthless and all point values are
modulo 10, with '9' the best possible hand value. We're using Punto Banco
rules with this simulation, if you're already an expert...
EOF
player[1]=${newdeck[1]}
player[2]=${newdeck[3]}
nextplayercard=3 # player starts with two cards
banker[1]=${newdeck[2]}
banker[2]=${newdeck[4]}
nextbankercard=3 # banker also has two cards
nextcard=5 # we've dealt the first four cards already
playerDrewCard=0 # not yet, at least
# now we show both hands and call out the values...
handValue ${player[1]} ${player[2]}
playerhandvalue=$handvalue
handValue ${banker[1]} ${banker[2]}
bankerhandvalue=$handvalue
# Step 1: show both hands, ascertain if there's an immediately endgame
# situation where player or banker has 8 or 9...
echo -n "** Player was dealt: "
showCard ${player[1]} ; echo -n "$cardname, "
showCard ${player[2]} ; echo "$cardname (hand value = $playerhandvalue)"
echo -n "** Banker was dealt: "
showCard ${banker[1]} ; echo -n "$cardname, "
showCard ${banker[2]} ; echo "$cardname (hand value = $bankerhandvalue)"
echo ""
if [ $playerhandvalue -ge 8 -o $bankerhandvalue -ge 8 ] ; then
echo -n "Play is complete. "
showResult
echo ""
exit 0
fi
# Step 2: Now, let's see if the player can draw a card. This can only
# happen if the player has an initial total of 0-5
if [ $playerhandvalue -lt 6 ] ; then
playerDrewCard=1
player[$nextplayercard]=${newdeck[$nextcard]}
handValue ${player[1]} ${player[2]} ${player[3]}
playerhandvalue=$handvalue
echo -n "Player takes a card: "; showCard ${player[$nextplayercard]}
echo "$cardname (hand value = $playerhandvalue)"
nextplayercard=$(( $nextplayercard + 1 ))
nextcard=$(( $nextcard + 1 ))
fi
# Step 3: the complicated rules of whether the Banker takes another
# card or not, the essence of what makes Baccarat an interesting game...
if [ $playerDrewCard -eq 0 ] ; then
if [ $bankerhandvalue -lt 6 ] ; then
dealBanker;
fi
else
# Player drew a card. Now the rules get complicated...
pdcRank=$(( ${player[3]} % 13 ))
if [ $pdcRank -eq 2 -o $pdcRank -eq 3 ] ; then
if [ $bankerhandvalue -lt 5 ]; then
dealBanker;
fi
elif [ $pdcRank -eq 4 -o $pdcRank -eq 5 ] ; then
if [ $bankerhandvalue -lt 6 ] ; then
dealBanker;
fi
elif [ $pdcRank -eq 6 -o $pdcRank -eq 7 ] ; then
if [ $bankerhandvalue -lt 7 ] ; then
dealBanker;
fi
elif [ $pdcRank -eq 8 -a $bankerhandvalue -lt 3 ] ; then
dealBanker;
elif [ $pdcRank -eq 9 -o $pdcRank -eq 0 ] ; then
if [ $bankerhandvalue -lt 4 ] ; then
dealBanker;
fi
fi
fi
echo ""
echo -n "Play is complete. "
showResult
echo ""
exit 0
Script – Eliminando Kernels antiguos
May 19th
Pequeño Script que permite seleccionar que kernel deseas eliminar (para Debian, Ubuntu o derivados).
#!/bin/bash if [ $USER != root ]; then echo -e "Tienes que ser root" echo -e "Saliendo..." exit 0 fi echo -e "---Kernel Instalados---" dpkg --get-selections | grep linux-image echo -e "Que kernel quieres eliminar?" read NOMBRE echo -e "Has elegido: $NOMBRE" echo -e "Seguro que deseas eliminar $NOMBRE?" OPCIONES="Si No" select opt in $OPCIONES; do if [ "$opt" = "Si" ]; then dpkg --purge $NOMBRE exit elif [ "$opt" = "No" ]; then echo -e "Saliendo..." exit else clear echo opción errónea fi done
Realizando GUI scripting con bash
Jul 14th
Cuando se trata de escribir aplicaciones personalizadas para servidores o equipos de escritorio en Linux, hay una serie de opciones de lenguajes que podemos usar. Puede escribir aplicaciones en Python, Perl, Ruby, o incluso PHP, entre tantos otros. Los scripts pueden ser escritos en el shell y, usando bash, zsh, o tcsh, por citar algunos. De todos ellos, la escritura de scripts en el shell (bash viene con casi todas las distribuciones Linux por ahí), es quizás el más fácil de aprender y la más rápida de escribir.
Lo bueno de un shell script es que, en sí mismo, no hay mucho que hacer en cuanto a programación. Los shell scripts son en realidad una secuencia de comandos que se escriben en la línea de comandos. Se admite las declaraciones de tipo if-then-else, admite bucles, y puede llegar a ser bastante complejo si queremos que sea, pero no tiene que serlo.
Y, al igual que otros lenguajes, los shell scripts pueden tener interfaces GUI (gráficos) también. Hay unas cuantas opciones diferentes como: Zenity para el escritorio GNOME, kdialog para el escritorio KDE, y un diálogo para TUI, ofreciendo menús y mensajes apropiados para la CLI. Un ejemplo del poder del uso de los shell scripts, es que podemos instalar un sistema operativo GNU/Linux desde bash, utilizando diálogos para realizar las preguntas sobre la instalación.
Con Zenity y kdialog, puede escribir una secuencia de comando que pregunten a los usuarios del sistema a través de ventanas GUI. Por ejemplo, para pedir al usuario que responder a una pregunta con un “Sí” o “No” se debería utilizar:
zenity --question "Do you wish to proceed?"
rc=$?
if [ "${rc}" == "0" ]; then
answer="yes"
else
answer="no"
fi
y el equivalente para kdialog:
kdialog --yesno "Do you wish to proceed?"
rc=$?
if [ "${rc}" == "0" ]; then
answer="yes"
else
answer="no"
fi
Ambos Zenity y kdialog mostrará más información con la opción de ayuda, y tiene una página de manual de Zenity que pueden ser referenciadas en busca de ayuda.
Otro ejemplo es en la creación de una barra de progreso. Por ejemplo, para mostrar una barra de progreso mientras se encuentran todos los archivos de copia de seguridad en su directorio principal, puede utilizar:
find . -name '*~' | tee >(zenity --progress --pulsate --title "Buscando fichero backups" --text "Buscando fichero backups...") >salida.txt zenity --width 400 --height 100 --title "File list" --text-info --filename=out.txt
kdialog trabaja de manera diferente, así que vamos a ver unos ejemplos. Vemos que tenemos que engañarlo con el uso de sleep, para realizar una espera. kdialog es un tanto especial.
ref=$(kdialog --progressbar "Buscando ficheros de backup" 3)
qdbus ${ref} org.kde.kdialog.ProgressDialog.setLabelText "Buscando ficheros de backup..."
qdbus ${ref} Set org.kde.kdialog.ProgressDialog value 1
find . -name '*~' >salida.txt
qdbus ${ref} Set org.kde.kdialog.ProgressDialog value 2
sleep 2
qdbus ${ref} Set org.kde.kdialog.ProgressDialog value 3
qdbus ${ref} org.kde.kdialog.ProgressDialog.close
kdialog --textbox salida.txt 400 100
Ambos mostrarán una barra de progreso (de muy corta duración) y luego se mostrará la salida del comando find (el cual se redirigio a salida.txt). Tenga en cuenta que en KDE3 kdialog es diferente que en KDE4 (el ejemplo es para KDE4). Si utiliza KDE3, la comunicación se realizá a través de DCOP, en lugar de DBUS.
Estas ilustraciones son muy simples, pero pueden demostrar las posibilidades de lo que puede hacerse con cualquier herramienta. De los dos, me parece Zenity mucho más fácil de trabajar, pero trabajan muy bien, tanto, y por supuesto depende de su entorno de elección.
La programación de GUI para shell scripts, con los programas de ayuda como Zenity y kdialog, es mucho más fácil de lograr que los programas de interfaz gráfica de usuario para entornos de programación. Si tiene que escribir un programa que requiere interacción del usuario, y también es necesario que la interacción sea a través del escritorio y no una terminal o shell, a continuación, estas herramientas pueden ayudar a alcanzar ese objetivo.
Si le ha servido de algo este artículo, deje un comentario en el mismo post.