==CPROG Journal== \\ //**9 4, 2014**// I learned a few interesting things today that I can reference to my experiences in VBS. When I first started VBS, I wrote some code for a number game. This game came along until I wrote a code to put data into a highscore file and read it back. I hadn't learned about variable-scopes yet, and I was racking my brain on why this variable's value would only work for some of the times I declared it. Finally, I asked for help from Joe and I discovered that I had set the variable locally; therefore, it would only have the set value inside of the function. In C You can declare the variable inside of a function also. You know you're in the function when you're in the {} curly brackets. Something I hadn't thought of was that setting global functions can make the code sloppy and also hinder you progress in obtaining better programming abilities. Another cool thing I learned was that inside of a function, you can create a sub-block in which the variables revert back to normal after-wards. One thing I am a little caught up on is grasping in the idea of pointers. I know that an asterisk is the symbol of a pointer, but I am still not entirely sure what they can do, besides point at integers. I am not ever sure what "pointing at an integer" is, but I am going to take a journey and try to grasp the concept by he end of the weekend. ==UNIX/Linux Fundamentals Journal== \\ //**9 5, 2014**// I seem to be doing very well in this class so far. I have been reading my Unix book and performing the exercises in the book __Unix for the beginning mage__, it's pretty amazing to be navigating around playing with files on as OS I have never even attempted to use. I enjoy being able to copy a directory and move it, then delete an entire directory with a few strokes of a keyboard. If I can do all of this already, who knows what possibilities in my future in unix/linux usage hold. I am so excited to learn and do more. ==CPROG Journal== \\ //**9 10, 2014**// I am starting to get a better grasp on the language of C and its syntax. I can now input and output and use the very basics of pointers. I can also perform math with a modulus on simple math programs. Something cool I did today was, converting a nott function from VBS to C. I am really enjoying this course and look forward to what it's future has to offer me. ==UNIX/Linux Fundamentals Journal== \\ //**9 10, 2014**// The further I climb in the rabbit hole, the more interesting UNIX/linux becomes. I have been crawling around using all sorts of ls arguments. Sometimes I know what I am doing and sometimes I don't. Either way, I learn something new a lot of the times. The only thing I am currently having trouble with is symbolic linking directories. They seem to end up looping one another. At this point I feel kind of sort of comfortable woth the man pages. Overall, this OS is a blast and I don't ever want to stop learning. ==CPROG Journal== //**9 14, 2014**// \\ \\ Now I am learning arrays, and getting ideas for all sorts of programs. When I come to a problem it is sort of like a puzzle that is fun to solve. I find myself coming up with program ideas. I can't wait to further develop my skills. ==UNIX/Linux Fundamentals Journal== \\ //**9 15, 2014**// I learned that in Linux, many of the tools needed for compressing and archiving are built in commands. I extracted files, sorted through them, and made my own archive. It is interesting for something I didn't know much about it. It was also pretty neat to lean that archiving lossy actually get rids of information. The thought of a lossy txt file is scary. It's a good thing we don't do that. ==UNIX/Linux Fundamentals Journal== \\ //**9 16, 2014**// A.Get file b.Using file(1), what type of file does this appear to be? It appears to be ASCII. c.View the contents of this file using cat(1). Is it what it appears to be? YES! This is a simple text file. It contains ASCII text. d.Using gzip(1), compress this file with default compression. What does file(1) say? It says, file.txt.gz: gzip compressed data, was "file.txt", last modified: Tue Sep 16 22:13:57 2014, from Unix. e.Uncompress the file, and recompress using arguments for fastest (not highest) compression. What does file(1) report now? file.txt.gz: gzip compressed data, was "file.txt", last modified: Tue Sep 16 22:13:57 2014, max speed, from Unix. **It is interesting that the file command reveals that the compressed data was max speed.** ===CPROG Journal=== \\ //**9 19, 2014**// **This Code I created resembles "mental-math" logic in squaring roots ending in 5.** As you would increment and multiple the tens+ digits and square the ones place. Then connect them together as one. 1 #include 2 main() 3 { 4 int var1; 5 printf("Type a 2 digit number ending in 5: "); 6 scanf("%d",&var1); 7 int dig1 = (var1/10); 8 int dig2 = dig1+1; 9 int fdig1 = dig1*dig2; 10 float dig3 = (var1%10); 11 int fdig2 = (dig3*dig3); 12 int whole = 25+(fdig1*100); 13 printf("The sqaure root of %d is: %d\n",var1,whole); 14 return(0); 15 } ~ As you can see, I did more math to get the result of an integer, instead of sort of connecting the two separate numbers to appear as one. This trick can even work for eight digit numbers ending in 5, but some integers higher than that will malfunction. ==CPROG Journal== \\ //**9 26, 2014**// \\ **I created a project involving an algorithm that produces what day new years is on.** \\ *I obtain the last two integers of the year. *I obtain the (integer) 25% value of that number in a "mental-math" way. (I do this by dividing 4). *I subtract 1 if it is a leap year (divisible by four). *I add the percent to the last two integers of the year. *I loop the value of 7, then subtract 7 to get the GCF of 7 in the result. *I subtract the multiple of the result and get the variable day. *I map the variable day to printf's with the proper days. \\ +#include +int main() +{ +int year, multiple; + printf("What year in the 21st century? : "); + scanf("%d",&year); + int tens = (year%100); + int percent = (tens/4); + if (tens%4==0) + { + percent = (percent-1); + } + int result=(percent+tens); + for (multiple=0;multiple ==UNIX/Linux fundamentals Journal== \\ //**9 30, 2014**// The PuzzleBox2 was my **UNIX adventure** this week. To do this project, I performed the following. lab46:~$ unzip puzzlebox2.zip Archive: puzzlebox2.zip [puzzlebox2.zip] big_endian.ascii password: I was then prompted for a password. This password was easy because it came in a README file. replace big_endian.ascii? [y]es, [n]o, [A]ll, [N]one, [r]ename: y inflating: big_endian.ascii [puzzlebox2.zip] part1 password: As you can see, I was given a file, and prompted for another password. I discovered that it was an ASCII file, so I converted the decimal to ASCII. Then I was left with Hex values to convert. I did this two times, first manually, second I ran this command. lab46:~$ cat stage2 | cut -d':' -f2 > $(cat stage2 | cut -d':' -f1).ascii This gave me the next password. Then I received 4 files with seemingly random contents named part1, part2, part3, and part4 (names not so random). Then I created the pipe command: lab46:~$ sort>|cat part1>|cat part2>|cat part3>|cat part4> result.txt **BOOM! FILES ARE ALL SORTED TOGETHER IN A SINGLE FILE, ALL WITH 1 COMMAND.! :)** This ends up making a picture using ASCII art. ==CPROG Journal== \\ //**10 7, 2014**// \\ **Switches** Can be used for if cases if exact value known is wanted.They are not good if there are more than 20 values, due to a wasteful amount typing. **switch example** \\ switch(variable) { case 0: code that describes the case. break; } repeat cases. **On another note** \\ This is th command needed to compile my code from the SDL library. gcc -o graphics graphics.c -lSDL -lSDL_image This links to the SDL library and to an SDL img lib. ==UNIX/Linux fundamentals Journal== \\ //**10 7, 2014**// \\ \\ __**PID**__ \\ \\ process-program in action.ps is a command that stands for process status. drep@Ghoste:~/Desktop$ ps PID TTY TIME CMD 3321 pts/1 00:00:00 bash 25153 pts/1 00:00:00 ps drep@Ghoste:~/Desktop$ top - 21:04:27 up 14 days, 21:59, 9 users, load average: 0.13, 0.07, 0.06 Tasks: 191 total, 1 running, 188 sleeping, 2 stopped, 0 zombie %Cpu(s): 0.2 us, 0.0 sy, 0.0 ni, 99.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem: 1535680 total, 656464 used, 879216 free, 49028 buffers KiB Swap: 131068 total, 107788 used, 23280 free. 331720 cached Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 13 root 20 0 0 0 0 S 0.3 0.0 31:56.26 ksoftirqd/1 1608 mp010784 20 0 19400 2328 648 S 0.3 0.2 22:43.79 tmux 20048 dsaunde6 20 0 129724 30260 5284 S 0.3 2.0 0:05.24 ruby 27183 dsoutha3 20 0 15912 1508 1048 R 0.3 0.1 0:00.04 top 1 root 20 0 15452 32 0 S 0.0 0.0 0:25.59 init 2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd 3 root 20 0 0 0 0 S 0.0 0.0 28:15.63 ksoftirqd/0 5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:+ 7 root 20 0 0 0 0 S 0.0 0.0 36:59.56 rcu_sched 8 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_bh 9 root rt 0 0 0 0 S 0.0 0.0 5:18.15 migration/0 10 root rt 0 0 0 0 S 0.0 0.0 2:43.12 watchdog/0 11 root rt 0 0 0 0 S 0.0 0.0 2:26.32 watchdog/1 12 root rt 0 0 0 0 S 0.0 0.0 4:49.83 migration/1 14 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kworker/1:0 15 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/1:+ 16 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 khelper **kill** \\ command that lets us generate signals kill -l kill list To just hang up kill kill -1 PID kill -HUP PUD The numbers are mapped to the 64 ways of killing. Number 9 cannot be stopped. It's the ultimate kill signal. \\ fms to see processes. \\ ps aux|grep $USER will list all \\ fg stands for foreground (re-animates stopped processes) \\ **Shell History** \\ parent shell is *sh -bourne shell from at&t made *bash *BSD- C shell \\ bg stands for background \\ jobs lists sleeping commands bg (job number) ===CPROG Journal=== \\ //**10 23, 2014**// *malloc - which stands for "memory-allocation" can be used to allocate specified amounts of memory. sizeof - function that returns the size of a specified datatype. \\ __**EXAMPLE (goes with our funcfun program.)**__ \\ \\ scores=(int*)malloc(sizeof(int)*num); size of returns thesize of an int and multiply's it by the number of ints aka num,(num=4 in this case), then malloc allocates the specified amount of memory. In this case, it will take 4 bytes times 4 bytes giving 16 bytes, which is just enough to store 4 integers.*/ *(scores+0) dereferences what's at the scores address and if you add you can dereference the things at the address shifted up from the starting adress. \\ __**DATA STRUCTURES**__ \\ *The WIKIPEDIA [[http://en.wikipedia.org/wiki/Struct_%28C_programming_language%29|Definition]] *A node is another word for a structure, they can be used together: structure node. *A structure pointer looks like this ->, instead of this *. \\ __**MATT'S STRUCTS CODE**__ \\ \\ /* * structs.c * * An example of using structs in C, along with arrays. * * To compile: gcc -o structs1 structs1.c * */ #include //#include int main() { int i; char entry[80], entries = 4, junk; struct person { char name[80]; int age; float height; }; do { printf("How many people in your database? "); scanf("%d", &entries); } while (entries <= 0); struct person people[entries]; for(i=0; i \\ __**Author, Designer, & Reviewer**__ \\ --- //[[|Derek Southard]] 2014/10/24 20:39// ==UNIX Journal== \\ //**10 23, 2014**// __**ALIAS**__ \\ *To set an alias: alias Name='command' *PS1='DerekJames$' : changes bash prompt to DerekJames. *Must be in a file set for log-on to re-apply the alias changes on log-in (.bashrc). *Here is a command that returns (the path variable) all of the directories that look for executables. lab46:~$ echo $PATH /usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games all of the places that terminal *PATH=$DesiredPath how to set command paths \\ \\ __**SHELL SCRIPTING**__ *Simply runs commands in file in order. *These files normally appear as in format of file.sh or file.bash. *#!/bin/bash basically a header to bash scripts, provides an absolute path to invoke the shell to run the script. *The read command reads input in bash, read name puts the input into name. For example, 1#!/bin/bash 2 echo -n "what is your name? " 3 read name 4 echo "hello, $name, nice to meet you" 5 exit 0 **output** \\ lab46:~$ ./src/unix/scripts/myscript.bash what is your name? Derek hello, Derek, nice to meet you \\ **Useful Knoweledge For Bash Beginners** *There are no data types, it's automatic. *if is a command and [ is a command. *if [ can be used together to compare things in an if statement better *[ itself can evaluate conditions. *else if in bash is an elif. *if statements get terminated with a fi. This is an end if in vbs. *exit0 terminates scripts *-eq numericaly = *-gt greater than *-lt less than ==UNIX Journal== \\ //**10 28, 2014**// \\ The bc command line calculator stands for binary calculator. \\ **Here is my bash script that finds my average ect. with comments explaining my logic** #!/bin/bash #OPUS GRADE earned=`status unix|grep opus|cut -d':' -f1|grep '1'|wc -l` total=`status unix|grep opus|cut -d':' -f1|wc -l` average=`echo "scale=3; $earned/$total*100"|bc` average=`echo "scale=1; $average/1"|bc` #PROJECT GRADE earned2=`echo|status unix|grep '.:.'|grep -v 'opus:week'|cut -d':' -f1|grep '1'|wc -l` total2=`echo|status unix|grep '.:.'|grep -v 'opus:week'|wc -l` average2=`echo "scale=3; $earned2/$total2*100"|bc` average2=`echo "scale=1; $average2/1"|bc` #ATTENDANCE GRADE earned3=`status unix|grep dsoutha3|cut -d']' -f2|tr -d [X]|wc -w` total3=`status unix|grep dsoutha3|cut -d']' -f2|wc -w` average3=`echo "scale=3; $earned3/$total3*100"|bc` average3=`echo "scale=1; $average3/1"|bc` #TOTAL GRADE ta=`echo "$average+$average2+$average3"|bc` ta=`echo "scale=1; $ta/3"|bc` #PRINT TABLE printf "\nOPUS\tPROJECTS\tATTENDANCE\n =====================================\n $earned/$total\t$earned2/$total2\t\t$earned3/$total3\n $average\t$average2\t\t$average3\n =====================================\n TOTAL AVERAGE: $ta percent\n\n" ==CPROG Journal== \\ //**10 28, 2014**// \\ __**fopen**__ \\ Some things we can do to files are open, read, write, append, create, remove/delete, and seek. We can do these things with the fopen function. This function has two parameters. p1 is for the path to filename, and p2 is for above mentioned thing to do. fopen returns a file pointer. \\ __**fgetc**__ \\ From MAN: fgetc() reads the next character from stream and returns it as an unsigned char cast to an int, or EOF on end of file or error. \n ==Code From Class== int main() { char c,b; int i, count=0; FILE *fptr; //file data type. FILE *fptr2; fptr2=fopen("txtt.txt","a"); b=fgetc(fptr2); fprintf (fptr2, "hey"); fptr=fopen("text.txt","r");// assigns the adress of file to file pointer if(fptr==NULL)// checking if file exists and has permission rights. { fprintf(stdout,"No such file or directory\n"); exit(1); } while((c=fgetc(fptr))!=EOF) { //(c=fgetc(fptr));if i left this fgetc in I would get every othe char. // fgetc takes a file pointer for arg, so putting are fptr in the function and the declaring c as its val. this makes c = the first char in the file. Then, we loop getting the chars in the file until we get the end of the file fprintf(stdout,"%c",c); }//Then we printf all of the chars until the loop ends which is at end of file. fclose(fptr); //closing file return(0); } ==My WC Code== int main (int argc, char * argv[]) { char chr, action; int wc=0,lc=0, cc=0,state; FILE *fptr;// declaring file pointer action = *(*(argv+2));// de-referencing argv2 twice and action setting it as the var actong get the charecter argument from the user. if (argc < 3)// checking if given args { fprintf(stderr, "You must specify agument(s)\n\nMAN PAGE\n\narg1\t\targ2\n======================\n\nFilename\tw\nFilename\tl\nFilename\tc\n\n======================\n\nw: counts words in file;\nl: counts lines in file;\nc: count charecters in file.\n\n"); exit(EXIT_FAILURE); //can use this or a non zero value for exit failure } fptr=fopen(argv[1],"r"); // setting the output of fopen which returns a fie pointer to file pointer. if (fptr == NULL)//check if file exists because fopen returns a value of NULL if the file isn't there or if you don't have the file permssions. { fprintf(stderr,"No such file or directory\n"); exit(EXIT_FAILURE); } while((chr=fgetc(fptr))!=EOF) //declaring chr as the charecters in the file until the file is empty. { cc++; // increment for every char if (chr=='\n') lc++; // increment ofr every new line if (chr==' '||chr=='\t'||chr=='\n') wc++;// increment every word } switch(action)// controll statement for which action was chosen by user { case 'w': fprintf(stdout,"%d words\n",wc); break; case 'l': fprintf(stdout,"%d lines\n",lc); break; case 'c': fprintf(stdout,"%d charecters\n",cc); break; } return(0); } ==CPROG JOURNAL== \\ \\ __**//11 4, 14//**__ \\ \\ Structures can't have functions, but they can have function pointers. Classes have member functions, but are only available in c++. Below, there is some code we wrote in the lab using creating a class named rectangle and using it. \\ class rectangle { public: // can be used outside of class int area(); int perimeter(); // member functions rectangle(); //function constructor, If class is instantiated (initiated) it runs automatically. rectangle(int,int); private: //can only be used in class int length; //member variables int width; }; int rectangle::area() //defining area as a member of the rectangle class { return((length*width)); } int rectangle::perimeter() //defining perimeter as a member of the rectangle class { return((length*2)+(width*2)); } rectangle::rectangle() { length=0; // looks in private, because there is no parameter. You variables and things you will need running in the constructor. width=0; } rectangle::rectangle(int length,int width) { this->length=length; // pointing at the class variables. this->width=width; } int main() { int area; int perimeter; area=0; perimeter=0; //declaring and defining the variables, then assigning them the value of 0 rectangle rect1; //defining an object rect1 from the rectangle class rectangle *rect2; //defining the object pointer, *rect2 rect2=new rectangle(4,10); //allocating memory from freestore using the key word "new" to create a pointer to my object. area=rect1.area();// assigning the value of the method area from tho object rect1 to the variable area. perimeter=rect1.perimeter(); // doing the same for method perimeter printf("rect1's area is %d\n",area); printf("rect1's perimeter is %d\n",perimeter); area=rect2->area();// assigns the output of the object pointer rect2 pointing to the method/member function area. perimeter=rect2->perimeter(); printf("rect2's area is %d\n",area); printf("rect2's perimeter is %d\n",perimeter); return(0); } If there is a ~ before a function like, ~rectangle(); it is a destructor. __**Access control**__ *public *protected *private Don't forget that I am the designer for the class notes wiki. ==UNIX JOURNAL== \\ \\ **//11 4, 14//** \\ \\ __//**RegEx**//__ \\ \\ *. -match any single character. ** -match 0 or more of the previous. *[] -match one of the enclosed. *[^] -don't match one of the enclosed. *\< -match start of word. *\> -match end of word. *^ -match start of line. *$ -match end of line. \\ \\ **Experimenting** \\ \\ Match lines with 4 or more chars that end with g $ cat words|grep '...g'|wc -l or $ cat words|grep '^....*g'|wc -l match lines with three or more only lower-case characters. cat words|grep '^[a-z][a-z][a-z][a-z]*$'|wc -l match all lines with at-least 3 or more lower-case vowels in it. cat words|grep '^.*[aeiouy].*[aeiouy].*[aeiouy].*$'|wc -l The .*'s Are for the possible characters in-between the vowels.\\ \\ __//**Extended RegEx**//__ \\ \\ *| -OR *() -grouping, some tools such as sed use \( \) for grouping. *+ -match 1 or more of the previous. \\ \\ egrep for extended grep \\ match all of the lines that end with ed or ing, cat words|egrep '(ed|ing)$'|wc -l ==UNIX JOURNAL== \\ \\ **//11 6, 14//** \\ sumbit unix statuscalc "scriptname" Awesomeness with sed lab46:~$ status unix|grep 'opus'|sed 's/^.*\([01]\):\([a-z][a-z]*\):\(week\)\([0-9]\)\(.*\)$/\5 for \3 \4 \2 [\1]/g' lab46:~$ getent passwd| grep '^[djs]' | sed 's/^\([djs][a-z0-9]*\):x:\([0-9][0-9][0-9] ==CPROG JOURNAL== \\ \\ **//11 15, 14//** \\ \\ **LINKED NODE CODE FROM CLASS** #include #include "SinglyLinkedNode.h" int main() { int i; SinglyLinkedNode *start=NULL; SinglyLinkedNode *tmp=NULL; SinglyLinkedNode *tmp2=NULL; //setting up List of Singly Linked Nodes start=new SinglyLinkedNode(7); start->setNext(new SinglyLinkedNode(39)); tmp=start->getNext(); //inserting a new node tmp2=new SinglyLinkedNode(73); tmp2->setNext(start->getNext()); start->setNext(tmp2); //setting tmp to point to starting node tmp=start; //print out our list with a loop while (tmp!=NULL) { printf("%d->", tmp->getValue()); tmp=tmp->getNext(); } printf("NULL\n"); return (0); } ==UNIX JOURNAL== \\ \\ **//11 15, 14//** \\ \\ [0-9]\):....:\(.*\):\/ho..*\(.*\).*$/\3 is user \1 with userid \2/g'\ for bash these variables are automatically made $# - count of arguments $* - all of your arguments "a b c" $0 - script name $1 - "a" $2 - "b" $3 - "c" man cron for status script every tuesday at 9 am put in tmp. ==UNIX PROJECT INSTRUCTIONS== \\ \\ using last take command-line argument, or user input if no arg $1 will be the first arg if [$1 is not NULL] get user-name elif echo What user? Then get input and check if the user exists. Proceed only if it does. then for each month of the users semester determine -number of logins for the month in histogram form. -total time spent on the system that month in days, hours, and mins. Total logins for semester, total time for semester. ==CPROG JOURNAL== \\ \\ I came up with a pretty neat idea. Its a fun way to see how arrays are stored in adresses. \\ The program takes a string, preserves its contents by copying it, navigates through the copy usings the spaces, and prints out its string along with its acronym. It also prints the memory adresses in which each char of the acronym is located at. Therefore, it gives a visual of each address the acronym chars. are stored at increasing 1 byte per string char. from the last adress in the output. \\ \\ **Source-Code and sample** \\ \\ #include #include void stringcopy(char*,char*); //declaring stringcopyfunction void getacr(char*); int main() { //int i=0; char string[50]; char copy[50]; printf("Type a string for an acronym: "); // storing string from command line to the array string fgets(string, sizeof(string), stdin); stringcopy(copy,string); //using string copy function i made(defined below) to get a copy of the string to preserve. fprintf(stdout,"\n\n%s\nACRONYM: ",string); getacr(copy);//using getacr function I made(defined below) to get acr of the copy. return(0); } void getacr(char* string) { printf("\n%c is at address of %p\n",*(string),(string)); while (*string!='\0') { string++; if ((*(string)==' ')||(*(string)=='-')) fprintf(stdout,"%c is at this address %p\n" ,*(string+1),(string+1)); } printf("\n"); //printf("%c",*(string)); //exit(0); } //printf("%c", *(copy+2)); void stringcopy(char *copy,char *string) //define stringcopy functions { while(*string!=EOF) // Loop while copy is not at string termination. { *copy=*string;//set the dereferenced value of string to copy then shift up to next adress space with next chat string++; copy++; } *copy='\0'; } **Sample** \\ \\ lab46:~/src/cscs1320-c$ ./acrAddress Type a string for an acronym: I Love The World Of Unix, And The Essence Of CSCI I Love The World Of Unix, And The Essence Of CSCI ACRONYM: I is at address of 0x7ffffdf70a60 L is at this address 0x7ffffdf70a62 T is at this address 0x7ffffdf70a67 W is at this address 0x7ffffdf70a6b O is at this address 0x7ffffdf70a71 U is at this address 0x7ffffdf70a74 A is at this address 0x7ffffdf70a7a T is at this address 0x7ffffdf70a7e E is at this address 0x7ffffdf70a82 O is at this address 0x7ffffdf70a8a C is at this address 0x7ffffdf70a8d ==UNIX JOURNAL WITH PROJECT REFLECTION VIA COMMENTS== \\ \\ #!/bin/bash ########################################################################################################################################### # Program that calulates log-data, by: Derek Southard # #getting username from user user=$1 if [ "$#" -eq 0 ]; then echo -n "Enter A Username: " read user fi echo $user check=`id $user 2>/dev/null | wc -l` #checking if user exists if [ "$check" -eq 0 ]; then echo User does not exist. exit 113 fi #grep -c ^$1: /etc/passwd #0 if user doesn't exists, 1 if user does. declare -a month=("Aug" "Sep" "Oct" "Nov" "Dec" "..*") # Declaring array as variable month and assigning elements of the months then ..* to capture all of the months (regex pattern for 1 or more of anything. index=0 for index in {0..5} do echo ${month[$index]} if [ $index -gt 4 ]; then echo "Complete Semester" fi echo "<+:~+:~+:~+:~+>" #LO Logins during the month of current array element. LO=`last|grep "${month[$index]}"|grep "$user"|wc -l` #capturing all minutes spent logged in. AM=`last|grep "$user"|grep "${month[$index]}"|grep -v 'still'|cut -d'(' -f2|tr -d ')'|cut -d':' -f2|tr '\n' '+'|tr -d '/n'` AM=`echo $AM|tr -d ' '` AM=${AM::-1} AM=`echo $AM|bc` #echo $AM all minutes #all minutes only minutes H=`echo "scale=2; $AM/60"|bc|cut -d'.' -f1` #echo hours gained from mins $H #hours by itself gained from overflowed mins from mins M=`echo "scale=2; $AM/60"|bc|cut -d'.' -f2` M=`echo "scale=1; .$M*60/1"|bc` #echo $M minutes after overflow buffer #time in minutes after the overflow was buffered AH=`last|grep "$user"|grep "${month[$index]}"|grep -v 'still'|cut -d'(' -f2|tr -d ')'|cut -d':' -f1|tr '\n' '+'` AH=${AH::-1} #deletes last char because there was an extra + at the end of data due to new line translation. AH=`echo $AH|bc` #echo $AH only hours no overflow mins #All hours only hours w/o the overflow minutes EH=`echo "$AH+$H"|bc` #echo $EH hours added #All hours added together with overflow minutes D=`echo "scale=2; $EH/24"|bc|cut -d'.' -f1` #echo $D days #Complete amount of days using overflowed hours BH=`echo "scale=2; $EH/24"|bc|cut -d'.' -f2` BH=`echo "scale=1; .$BH*24/1"|bc` #echo $BH hours after days calculated #Hours after day buffer has taken overflow echo Logins: $LO Time logged in: $D Days, $BH Hours, and $M minutes. echo " " index=$index+1 done echo *HISTOGRAM* index=0 #embedded loop to print an = symbol for every login for every month. for index in {0..4} do j=0 LO=`last|grep "${month[$index]}"|grep "$user"|wc -l` printf "${month[$index]}: " while [ $j -lt $LO ]; do printf "=" let j=$j+1 done echo " $LO logins" printf "\n" done dsoutha3 Aug <+:~+:~+:~+:~+> Logins: 20 Time logged in: 1 Days, 0 Hours, and 3.0 minutes. Sep <+:~+:~+:~+:~+> Logins: 124 Time logged in: 10 Days, 13.9 Hours, and 12.0 minutes. Oct <+:~+:~+:~+:~+> Logins: 113 Time logged in: 8 Days, 8.8 Hours, and 3.6 minutes. Nov <+:~+:~+:~+:~+> Logins: 41 Time logged in: 1 Days, 21.8 Hours, and 16.8 minutes. Dec <+:~+:~+:~+:~+> Logins: 7 Time logged in: Days, 9.8 Hours, and 3.6 minutes. .. Complete Semester <+:~+:~+:~+:~+> Logins: 305 Time logged in: 22 Days, 6.9 Hours, and 39.6 minutes. *HISTOGRAM* Aug: ==================== 20 logins Sep: ============================================================================================================================ 124 logins Oct: ================================================================================================================= 113 logins Nov: ========================================= 41 logins Dec: ======= 7 logins